

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=dark>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/memory_blog/img/fluid.png">
  <link rel="icon" href="/memory_blog/img/icon/dw.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="Memory">
  <meta name="keywords" content="">
  
    <meta name="description" content="🍨 记录我的Spring Boot之旅，从困境到胜利，与你分享不平凡的成长历程">
<meta property="og:type" content="article">
<meta property="og:title" content="凤凰涅槃：Spring Boot 开发之路上的坎坷与成长">
<meta property="og:url" content="https://test.atomgit.net/memory_blog/2023/07/06/%E5%87%A4%E5%87%B0%E6%B6%85%E6%A7%83%EF%BC%9ASpring%20Boot%20%E5%BC%80%E5%8F%91%E4%B9%8B%E8%B7%AF%E4%B8%8A%E7%9A%84%E5%9D%8E%E5%9D%B7%E4%B8%8E%E6%88%90%E9%95%BF/index.html">
<meta property="og:site_name" content="Memory&#39;s blog">
<meta property="og:description" content="🍨 记录我的Spring Boot之旅，从困境到胜利，与你分享不平凡的成长历程">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://test.atomgit.net/memory_blog/img/artical/mountain0414.jpg">
<meta property="article:published_time" content="2023-07-06T10:04:25.000Z">
<meta property="article:modified_time" content="2024-06-04T10:18:54.000Z">
<meta property="article:author" content="Memory">
<meta property="article:tag" content="经验">
<meta property="article:tag" content="项目">
<meta property="article:tag" content="Redis">
<meta property="article:tag" content="SpringBoot">
<meta property="article:tag" content="Mybatis">
<meta property="article:tag" content="阿里云OSS">
<meta property="article:tag" content="接口文档">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://test.atomgit.net/memory_blog/img/artical/mountain0414.jpg">
  
  
  
  <title>凤凰涅槃：Spring Boot 开发之路上的坎坷与成长 - Memory&#39;s blog</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/memory_blog/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/memory_blog/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/memory_blog/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"test.atomgit.net","root":"/memory_blog/","version":"1.9.4","typing":{"enable":true,"typeSpeed":100,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":false,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":true,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/memory_blog/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/memory_blog/js/utils.js" ></script>
  <script  src="/memory_blog/js/color-schema.js" ></script>
  

  

  

  

  

  

  

  



  
<meta name="generator" content="Hexo 5.4.2"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 75vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/memory_blog/">
      <strong>Memory&#39;s blog</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/memory_blog/">
                <i class="iconfont icon-home-fill"></i>
                <span>首页</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/memory_blog/archives/">
                <i class="iconfont icon-archive-fill"></i>
                <span>归档</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/memory_blog/categories/">
                <i class="iconfont icon-category-fill"></i>
                <span>分类</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/memory_blog/tags/">
                <i class="iconfont icon-tags-fill"></i>
                <span>标签</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/memory_blog/about/">
                <i class="iconfont icon-user-fill"></i>
                <span>关于</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/memory_blog/links/">
                <i class="iconfont icon-link-fill"></i>
                <span>友链</span>
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              <i class="iconfont icon-search"></i>
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">
              <i class="iconfont icon-dark" id="color-toggle-icon"></i>
            </a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/memory_blog/img/newBG/girl.jpg') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="凤凰涅槃：Spring Boot 开发之路上的坎坷与成长"></span>
          
        </div>

        
          
  <div class="mt-3">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-author" aria-hidden="true"></i>
        Memory
      </span>
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2023-07-06 18:04" pubdate>
          2023年7月6日 晚上
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          58k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          145 分钟
        
      </span>
    

    
    
      
        <span id="leancloud-page-views-container" class="post-meta" style="display: none">
          <i class="iconfont icon-eye" aria-hidden="true"></i>
          <span id="leancloud-page-views"></span> 次
        </span>
        
      
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar category-bar" style="margin-right: -1rem">
    





<div class="category-list">
  
  
    
    
    
    <div class="category row nomargin-x">
      <a class="category-item 
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="SpringBoot"
        id="heading-c8428a45869e78fb361ed20b9c23b0a8" role="tab" data-toggle="collapse" href="#collapse-c8428a45869e78fb361ed20b9c23b0a8"
        aria-expanded="true"
      >
        SpringBoot
        <span class="list-group-count">(3)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse show" id="collapse-c8428a45869e78fb361ed20b9c23b0a8"
           role="tabpanel" aria-labelledby="heading-c8428a45869e78fb361ed20b9c23b0a8">
        
        
          
          
  <div class="category-post-list">
    
    
  </div>

          
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem 
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="Mybatis"
        id="heading-dcfb60bf74123650041eacb77b10c116" role="tab" data-toggle="collapse" href="#collapse-dcfb60bf74123650041eacb77b10c116"
        aria-expanded="true"
      >
        Mybatis
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse show" id="collapse-dcfb60bf74123650041eacb77b10c116"
           role="tabpanel" aria-labelledby="heading-dcfb60bf74123650041eacb77b10c116">
        
        
          
          
  <div class="category-post-list">
    
    
  </div>

          
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem 
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="Redis"
        id="heading-e111446745a1825b862f8727ae63bce4" role="tab" data-toggle="collapse" href="#collapse-e111446745a1825b862f8727ae63bce4"
        aria-expanded="true"
      >
        Redis
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse show" id="collapse-e111446745a1825b862f8727ae63bce4"
           role="tabpanel" aria-labelledby="heading-e111446745a1825b862f8727ae63bce4">
        
        
          
          
  <div class="category-post-list">
    
    
  </div>

          
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem 
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="阿里云OSS"
        id="heading-a4bd7c032dc05684f30d3c80c60cf16e" role="tab" data-toggle="collapse" href="#collapse-a4bd7c032dc05684f30d3c80c60cf16e"
        aria-expanded="true"
      >
        阿里云OSS
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse show" id="collapse-a4bd7c032dc05684f30d3c80c60cf16e"
           role="tabpanel" aria-labelledby="heading-a4bd7c032dc05684f30d3c80c60cf16e">
        
        
          
          
  <div class="category-post-list">
    
    
  </div>

          
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem 
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="接口文档"
        id="heading-062d05a45d82ada305bd81b164f6df02" role="tab" data-toggle="collapse" href="#collapse-062d05a45d82ada305bd81b164f6df02"
        aria-expanded="true"
      >
        接口文档
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse show" id="collapse-062d05a45d82ada305bd81b164f6df02"
           role="tabpanel" aria-labelledby="heading-062d05a45d82ada305bd81b164f6df02">
        
        
          
          
  <div class="category-post-list">
    
    
  </div>

          
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem 
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="经验"
        id="heading-32a8e000e928e6dc255876d9fc0178b3" role="tab" data-toggle="collapse" href="#collapse-32a8e000e928e6dc255876d9fc0178b3"
        aria-expanded="true"
      >
        经验
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse show" id="collapse-32a8e000e928e6dc255876d9fc0178b3"
           role="tabpanel" aria-labelledby="heading-32a8e000e928e6dc255876d9fc0178b3">
        
        
          
          
  <div class="category-post-list">
    
    
  </div>

          
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem 
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="项目"
        id="heading-31ecc0e65b4cd3e6b12577382bb56d6a" role="tab" data-toggle="collapse" href="#collapse-31ecc0e65b4cd3e6b12577382bb56d6a"
        aria-expanded="true"
      >
        项目
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse show" id="collapse-31ecc0e65b4cd3e6b12577382bb56d6a"
           role="tabpanel" aria-labelledby="heading-31ecc0e65b4cd3e6b12577382bb56d6a">
        
        
          
  <div class="category-post-list">
    
    
      
      
        <a href="/memory_blog/2023/07/06/%E5%87%A4%E5%87%B0%E6%B6%85%E6%A7%83%EF%BC%9ASpring%20Boot%20%E5%BC%80%E5%8F%91%E4%B9%8B%E8%B7%AF%E4%B8%8A%E7%9A%84%E5%9D%8E%E5%9D%B7%E4%B8%8E%E6%88%90%E9%95%BF/" title="凤凰涅槃：Spring Boot 开发之路上的坎坷与成长"
           class="list-group-item list-group-item-action
           active">
          <span class="category-post">凤凰涅槃：Spring Boot 开发之路上的坎坷与成长</span>
        </a>
      
    
  </div>

        
      </div>
    </div>
  
        
      </div>
    </div>
  
        
      </div>
    </div>
  
        
      </div>
    </div>
  
        
      </div>
    </div>
  
        
      </div>
    </div>
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem collapsed
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="经验"
        id="heading-32a8e000e928e6dc255876d9fc0178b3" role="tab" data-toggle="collapse" href="#collapse-32a8e000e928e6dc255876d9fc0178b3"
        aria-expanded="false"
      >
        经验
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse " id="collapse-32a8e000e928e6dc255876d9fc0178b3"
           role="tabpanel" aria-labelledby="heading-32a8e000e928e6dc255876d9fc0178b3">
        
        
          
          
  <div class="category-post-list">
    
    
  </div>

          
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem collapsed
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="项目"
        id="heading-31ecc0e65b4cd3e6b12577382bb56d6a" role="tab" data-toggle="collapse" href="#collapse-31ecc0e65b4cd3e6b12577382bb56d6a"
        aria-expanded="false"
      >
        项目
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse " id="collapse-31ecc0e65b4cd3e6b12577382bb56d6a"
           role="tabpanel" aria-labelledby="heading-31ecc0e65b4cd3e6b12577382bb56d6a">
        
        
          
  <div class="category-post-list">
    
    
      
      
        <a href="/memory_blog/2023/08/23/SpringBoot%E7%AC%AC%E4%B8%89%E6%96%B9%E6%9C%8D%E5%8A%A1%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5%EF%BC%9A%E7%89%88%E6%9C%AC%E5%85%BC%E5%AE%B9%E6%80%A7%E5%92%8C%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86/" title="SpringBoot第三方服务开发实践：版本兼容性和依赖管理"
           class="list-group-item list-group-item-action
           ">
          <span class="category-post">SpringBoot第三方服务开发实践：版本兼容性和依赖管理</span>
        </a>
      
    
  </div>

        
      </div>
    </div>
  
        
      </div>
    </div>
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem collapsed
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="项目"
        id="heading-31ecc0e65b4cd3e6b12577382bb56d6a" role="tab" data-toggle="collapse" href="#collapse-31ecc0e65b4cd3e6b12577382bb56d6a"
        aria-expanded="false"
      >
        项目
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse " id="collapse-31ecc0e65b4cd3e6b12577382bb56d6a"
           role="tabpanel" aria-labelledby="heading-31ecc0e65b4cd3e6b12577382bb56d6a">
        
        
          
          
  <div class="category-post-list">
    
    
  </div>

          
  
    
    
    
    <div class="category-sub row nomargin-x">
      <a class="category-subitem collapsed
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="经验"
        id="heading-32a8e000e928e6dc255876d9fc0178b3" role="tab" data-toggle="collapse" href="#collapse-32a8e000e928e6dc255876d9fc0178b3"
        aria-expanded="false"
      >
        经验
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse " id="collapse-32a8e000e928e6dc255876d9fc0178b3"
           role="tabpanel" aria-labelledby="heading-32a8e000e928e6dc255876d9fc0178b3">
        
        
          
  <div class="category-post-list">
    
    
      
      
        <a href="/memory_blog/2023/08/05/%E7%90%B4%E7%91%9F%E5%92%8C%E9%B8%A3%EF%BC%9A%E5%AE%9A%E5%88%B6%E5%8C%96%20Spring%20Boot%20Starter%EF%BC%8C%E8%AE%A9%E4%BD%A0%E7%9A%84%E6%8E%A5%E5%8F%A3%E8%B0%83%E7%94%A8%E5%A6%82%E8%A1%8C%E4%BA%91%E6%B5%81%E6%B0%B4%E8%88%AC%E8%87%AA%E7%84%B6/" title="琴瑟和鸣：定制化 Spring Boot Starter，让你的接口调用如行云流水般自然"
           class="list-group-item list-group-item-action
           ">
          <span class="category-post">琴瑟和鸣：定制化 Spring Boot Starter，让你的接口调用如行云流水般自然</span>
        </a>
      
    
  </div>

        
      </div>
    </div>
  
        
      </div>
    </div>
  
        
      </div>
    </div>
  
</div>


  </aside>


    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">凤凰涅槃：Spring Boot 开发之路上的坎坷与成长</h1>
            
              <p class="note note-success">
                
                  
                    本文最后更新于：1 个月前
                  
                
              </p>
            
            
              <div class="markdown-body">
                
                <p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/mountain0414.jpg" alt="生命的旅程就像一场冒险，每一步都充满了未知与惊喜。"></p>
<h1 id="破冰"><a href="#破冰" class="headerlink" title="破冰"></a>破冰</h1><h2 id="写作目标"><a href="#写作目标" class="headerlink" title="写作目标"></a>写作目标</h2><p>今天是开发壁纸网站 memory-icon 的第一天，本来没打算写什么开发文档的，太耗时间，整体实现思路也简单，就不写了</p>
<p>但是有必要记录一下：从零开发一个SpringBoot项目，至少应该要做些什么</p>
<p>这就算给定制自己的 SpringBoot 模板开个好头了（2023/08/01午）</p>
<h2 id="开发思路"><a href="#开发思路" class="headerlink" title="开发思路"></a>开发思路</h2><p><strong>从零开发一个SpringBoot要做什么？一定是做到以下几点：（2023/08/01午）</strong></p>
<ul>
<li><p>新建模块</p>
</li>
<li><p>导入必要的依赖：MySQL、Mybatis、MybatisPlus、commons-lang3、lombok、Gson等</p>
</li>
<li><p>新增必要yaml配置：项目名、启动端口、上下文路径、数据库地址</p>
</li>
<li><p>新增banner.txt</p>
</li>
<li><p>新增数据库表，连接数据库，保存建表语句</p>
</li>
<li><p>新增controller层、service层</p>
</li>
<li><p>利用MybatisX-Generator插件，快速生成domain、mapper、service、XXXMaper.xml</p>
</li>
<li><p>新增config层：CorsConfig、MybatisPlusConfig、Knife4jConfig、JsonConfig等</p>
</li>
</ul>
<h1 id="思维碰撞"><a href="#思维碰撞" class="headerlink" title="思维碰撞"></a>思维碰撞</h1><h2 id="着手开发"><a href="#着手开发" class="headerlink" title="着手开发"></a>着手开发</h2><h3 id="快速编写Controller层"><a href="#快速编写Controller层" class="headerlink" title="快速编写Controller层"></a>快速编写Controller层</h3><ul>
<li><h5 id="什么是Controller层？（2023-08-14早）"><a href="#什么是Controller层？（2023-08-14早）" class="headerlink" title="什么是Controller层？（2023/08/14早）"></a>什么是Controller层？（2023/08/14早）</h5></li>
</ul>
<figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs livecodeserver">在Web开发中，Controller层是MVC（模型-视图-控制器）架构的一部分，用于接收并处理前端请求。<br>具体来说，Controller层负责以下几个任务：<br>	<span class="hljs-number">1.</span>接收HTTP请求：Controller通过定义特定的路由（<span class="hljs-built_in">URL</span>映射）来接收前端发送的HTTP请求。<br>	<span class="hljs-number">2.</span>处理请求：Controller中的方法将根据请求的类型、路径以及请求参数等信息，执行相应的逻辑操作。<br>	<span class="hljs-number">3.</span>调用服务层：在Controller中，可以调用服务层（Service层、业务层）的方法来实现相关业务逻辑。<br>	<span class="hljs-number">4.</span>返回响应：在完成对请求的处理后，Controller负责将数据或者视图响应返回给前端。<br>Controller层的目标是实现请求-响应的流程控制，将请求按照业务逻辑分配给对应的服务层处理，并将执行结果返回给前端。同时，Controller层还可以处理一些与业务逻辑相关的验证或者数据转换等操作。<br></code></pre></td></tr></table></figure>

<ul>
<li>引入依赖：</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>			<span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>			<span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>			<span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.7.14<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>		<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="这里贴个小技巧，alt-insert-快速添加依赖模板："><a href="#这里贴个小技巧，alt-insert-快速添加依赖模板：" class="headerlink" title="这里贴个小技巧，alt + insert 快速添加依赖模板："></a>这里贴个小技巧，alt + insert 快速添加依赖模板：</h5></li>
</ul>
<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230814130719252.png" alt="image-20230814130719252"></p>
<ul>
<li><h5 id="新增controller层，编写响应请求的逻辑："><a href="#新增controller层，编写响应请求的逻辑：" class="headerlink" title="新增controller层，编写响应请求的逻辑："></a>新增controller层，编写响应请求的逻辑：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author</span> 邓哈哈</span><br><span class="hljs-comment"> * 2023/8/14 12:06</span><br><span class="hljs-comment"> * Function:</span><br><span class="hljs-comment"> * Version 1.0</span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-meta">@RestController</span><br><span class="hljs-meta">@RequestMapping(&quot;/test&quot;)</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TestController</span> &#123;<br>    <span class="hljs-meta">@GetMapping(&quot;/name&quot;)</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getName</span><span class="hljs-params">(String name)</span> &#123;<br>        <span class="hljs-keyword">return</span> String.format(<span class="hljs-string">&quot;我的名字是: %s&quot;</span>, name);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="编辑-application-yaml-配置文件："><a href="#编辑-application-yaml-配置文件：" class="headerlink" title="编辑 application.yaml 配置文件："></a>编辑 application.yaml 配置文件：</h5></li>
</ul>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">server:</span><br>  <span class="hljs-attr">port:</span> <span class="hljs-number">8088</span><br>  <span class="hljs-attr">servlet:</span><br>    <span class="hljs-attr">context-path:</span> <span class="hljs-string">/api</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="发送请求，测试接口"><a href="#发送请求，测试接口" class="headerlink" title="发送请求，测试接口"></a>发送请求，测试接口</h5></li>
<li><p>这一步的操作方法有很多：</p>
<ul>
<li>Postman工具</li>
<li>Swagger + Knif4j 接口文档</li>
<li>浏览器</li>
<li>IDEA模拟浏览器</li>
</ul>
</li>
<li><h5 id="有关Postman工具的使用，这里不再详述"><a href="#有关Postman工具的使用，这里不再详述" class="headerlink" title="有关Postman工具的使用，这里不再详述"></a>有关Postman工具的使用，这里不再详述</h5></li>
<li><h5 id="有关快速生成-Swagger-Knif4j-接口文档的教程，可以在下面👇的《快速生成-Swagger-Knif4j接口文档》栏目中了解到"><a href="#有关快速生成-Swagger-Knif4j-接口文档的教程，可以在下面👇的《快速生成-Swagger-Knif4j接口文档》栏目中了解到" class="headerlink" title="有关快速生成 Swagger + Knif4j 接口文档的教程，可以在下面👇的《快速生成 Swagger + Knif4j接口文档》栏目中了解到"></a>有关快速生成 Swagger + Knif4j 接口文档的教程，可以在下面👇的《快速生成 Swagger + Knif4j接口文档》栏目中了解到</h5></li>
<li><h5 id="有关IDEA如何模拟浏览器，发送HTTP请求，可以在《掌握-JetBrains-IntelliJ-IDEA：使用心得与技巧》一文中的《模拟浏览器发送请求》栏目中找到答案"><a href="#有关IDEA如何模拟浏览器，发送HTTP请求，可以在《掌握-JetBrains-IntelliJ-IDEA：使用心得与技巧》一文中的《模拟浏览器发送请求》栏目中找到答案" class="headerlink" title="有关IDEA如何模拟浏览器，发送HTTP请求，可以在《掌握-JetBrains-IntelliJ-IDEA：使用心得与技巧》一文中的《模拟浏览器发送请求》栏目中找到答案"></a>有关IDEA如何模拟浏览器，发送HTTP请求，可以在《掌握-JetBrains-IntelliJ-IDEA：使用心得与技巧》一文中的《模拟浏览器发送请求》栏目中找到答案</h5></li>
<li><h5 id="有关SpringMVC处理HTTP请求参数的方式，可以在《SpringBoot配置》一文中的-《SpringMVC-请求参数的处理》栏目中找到答案"><a href="#有关SpringMVC处理HTTP请求参数的方式，可以在《SpringBoot配置》一文中的-《SpringMVC-请求参数的处理》栏目中找到答案" class="headerlink" title="有关SpringMVC处理HTTP请求参数的方式，可以在《SpringBoot配置》一文中的 《SpringMVC 请求参数的处理》栏目中找到答案"></a>有关SpringMVC处理HTTP请求参数的方式，可以在《SpringBoot配置》一文中的 《SpringMVC 请求参数的处理》栏目中找到答案</h5></li>
<li><p>浏览器发送请求，结果如下图所示：（2023/08/14午）</p>
</li>
</ul>
<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230814132007439.png" alt="image-20230814132007439"></p>
<ul>
<li>IDEA模拟浏览器发送请求，结果如下图所示：</li>
</ul>
<figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs http">GET http://localhost:8088/api/test/name?name=邓啊呀<br></code></pre></td></tr></table></figure>

<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230814132051083.png" alt="image-20230814132051083"></p>
<h3 id="全局异常处理"><a href="#全局异常处理" class="headerlink" title="全局异常处理"></a>全局异常处理</h3><h3 id="MybatisPlus"><a href="#MybatisPlus" class="headerlink" title="MybatisPlus"></a>MybatisPlus</h3><ul>
<li><p>官方文档：<a target="_blank" rel="noopener" href="https://baomidou.com/">MyBatis-Plus (baomidou.com)</a></p>
</li>
<li><h5 id="导入依赖坐标：（2023-08-21早）"><a href="#导入依赖坐标：（2023-08-21早）" class="headerlink" title="导入依赖坐标：（2023/08/21早）"></a>导入依赖坐标：（2023/08/21早）</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>     <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.baomidou<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>     <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mybatis-plus-boot-starter<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>     <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.4.2<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br> <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li>配置:</li>
</ul>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">mybatis-plus:</span><br>  <span class="hljs-attr">configuration:</span><br>    <span class="hljs-comment">#在映射实体或者属性时，将数据库中表名和字段名中的下划线去掉，按照驼峰命名法映射</span><br>    <span class="hljs-attr">map-underscore-to-camel-case:</span> <span class="hljs-literal">true</span><br>    <span class="hljs-attr">log-impl:</span> <span class="hljs-string">org.apache.ibatis.logging.stdout.StdOutImpl</span> <span class="hljs-comment"># 开启SQL日志</span><br>  <span class="hljs-attr">global-config:</span><br>    <span class="hljs-attr">db-config:</span><br>      <span class="hljs-attr">id-type:</span> <span class="hljs-string">ASSIGN_ID</span> <span class="hljs-comment"># 主键自增长策略</span><br>      <span class="hljs-attr">logic-delete-field:</span> <span class="hljs-string">isDelete</span> <span class="hljs-comment"># 全局逻辑删除的实体字段名</span><br>      <span class="hljs-attr">logic-delete-value:</span> <span class="hljs-number">1</span> <span class="hljs-comment"># 逻辑已删除值（默认为 1）</span><br>      <span class="hljs-attr">logic-not-delete-value:</span> <span class="hljs-number">0</span> <span class="hljs-comment"># 逻辑未删除值（默认为 0）</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="以上是最常用的配置，其中，按照驼峰命名法映射是这样处理的："><a href="#以上是最常用的配置，其中，按照驼峰命名法映射是这样处理的：" class="headerlink" title="以上是最常用的配置，其中，按照驼峰命名法映射是这样处理的："></a>以上是最常用的配置，其中，按照驼峰命名法映射是这样处理的：</h5><ul>
<li><p>建库建表后，如果表字段是下划线命名的，而实体类是驼峰命名，如下：</p>
</li>
<li><p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230821115235186.png" alt="image-20230821115235186"></p>
</li>
<li><h5 id="当我们操作数据库时，MybatisPlus会将驼峰命名的实体类属性，映射为下划线命名的表字段了："><a href="#当我们操作数据库时，MybatisPlus会将驼峰命名的实体类属性，映射为下划线命名的表字段了：" class="headerlink" title="当我们操作数据库时，MybatisPlus会将驼峰命名的实体类属性，映射为下划线命名的表字段了："></a>当我们操作数据库时，MybatisPlus会将驼峰命名的实体类属性，映射为下划线命名的表字段了：</h5></li>
<li><p>```java<br>boolean updateById = setMealService.updateById(setmeal);</p>
<figure class="highlight clean"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs clean"><br>- ##### 开启SQL日志不用多说，方便代码调试和分析报错信息<br><br>- ##### 主键自增长策略，也可以在主键字段上添加注解：<br><br>```java<br>  <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 主键</span><br><span class="hljs-comment">     */</span><br>    @TableId(value = <span class="hljs-string">&quot;id&quot;</span>, type = IdType.AUTO)<br>    private Long id;<br></code></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>逻辑删除，被删除的数据记录不会直接从表中删除，而是在指定字段上标注为已删除，需要在字段上添加以下注解：</p>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   * 是否删除(0-未删, 1-已删)</span><br><span class="hljs-comment">   */</span><br>  <span class="hljs-meta">@TableField(value = &quot;isDelete&quot;)</span><br>  <span class="hljs-meta">@TableLogic</span><br>  <span class="hljs-keyword">private</span> Integer isDelete;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="最后在WebConfig下配置分页插件：（2023-08-22早）"><a href="#最后在WebConfig下配置分页插件：（2023-08-22早）" class="headerlink" title="最后在WebConfig下配置分页插件：（2023/08/22早）"></a>最后在WebConfig下配置分页插件：（2023/08/22早）</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * Web配置类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@Configuration</span><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">WebConfig</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">WebMvcConfigurer</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 分页插件（官网最新）</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Bean</span><br>    <span class="hljs-keyword">public</span> MybatisPlusInterceptor <span class="hljs-title function_">mybatisPlusInterceptor</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-type">MybatisPlusInterceptor</span> <span class="hljs-variable">interceptor</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">MybatisPlusInterceptor</span>();<br>        interceptor.addInnerInterceptor(<span class="hljs-keyword">new</span> <span class="hljs-title class_">PaginationInnerInterceptor</span>(DbType.MYSQL));<br>        <span class="hljs-keyword">return</span> interceptor;<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="对象映射器（消息转换器）"><a href="#对象映射器（消息转换器）" class="headerlink" title="对象映射器（消息转换器）"></a>对象映射器（消息转换器）</h3><ul>
<li><h5 id="编写JacksonObjectMapper：（2023-08-22早）"><a href="#编写JacksonObjectMapper：（2023-08-22早）" class="headerlink" title="编写JacksonObjectMapper：（2023/08/22早）"></a>编写JacksonObjectMapper：（2023/08/22早）</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 对象映射器:基于jackson将Java对象转为json，或者将json转为Java对象</span><br><span class="hljs-comment"> * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]</span><br><span class="hljs-comment"> * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">JacksonObjectMapper</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">ObjectMapper</span> &#123;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">String</span> <span class="hljs-variable">DEFAULT_DATE_FORMAT</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;yyyy-MM-dd&quot;</span>;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">String</span> <span class="hljs-variable">DEFAULT_DATE_TIME_FORMAT</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;yyyy-MM-dd HH:mm:ss&quot;</span>;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">String</span> <span class="hljs-variable">DEFAULT_TIME_FORMAT</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;HH:mm:ss&quot;</span>;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">JacksonObjectMapper</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-built_in">super</span>();<br>        <span class="hljs-comment">//收到未知属性时不报异常</span><br>        <span class="hljs-built_in">this</span>.configure(FAIL_ON_UNKNOWN_PROPERTIES, <span class="hljs-literal">false</span>);<br><br>        <span class="hljs-comment">//反序列化时，属性不存在的兼容处理</span><br>        <span class="hljs-built_in">this</span>.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);<br><br><br>        <span class="hljs-type">SimpleModule</span> <span class="hljs-variable">simpleModule</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SimpleModule</span>()<br>                .addDeserializer(LocalDateTime.class, <span class="hljs-keyword">new</span> <span class="hljs-title class_">LocalDateTimeDeserializer</span>(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))<br>                .addDeserializer(LocalDate.class, <span class="hljs-keyword">new</span> <span class="hljs-title class_">LocalDateDeserializer</span>(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))<br>                .addDeserializer(LocalTime.class, <span class="hljs-keyword">new</span> <span class="hljs-title class_">LocalTimeDeserializer</span>(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))<br><br>                .addSerializer(BigInteger.class, ToStringSerializer.instance)<br>                .addSerializer(Long.class, ToStringSerializer.instance)<br>                .addSerializer(LocalDateTime.class, <span class="hljs-keyword">new</span> <span class="hljs-title class_">LocalDateTimeSerializer</span>(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))<br>                .addSerializer(LocalDate.class, <span class="hljs-keyword">new</span> <span class="hljs-title class_">LocalDateSerializer</span>(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))<br>                .addSerializer(LocalTime.class, <span class="hljs-keyword">new</span> <span class="hljs-title class_">LocalTimeSerializer</span>(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));<br><br>        <span class="hljs-comment">//注册功能模块 例如，可以添加自定义序列化器和反序列化器</span><br>        <span class="hljs-built_in">this</span>.registerModule(simpleModule);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="在WebConfig下作如下配置："><a href="#在WebConfig下作如下配置：" class="headerlink" title="在WebConfig下作如下配置："></a>在WebConfig下作如下配置：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * Web配置类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@Configuration</span><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">WebConfig</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">WebMvcConfigurer</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 扩展消息转换器</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> converters converters</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">extendMessageConverters</span><span class="hljs-params">(List&lt;HttpMessageConverter&lt;?&gt;&gt; converters)</span> &#123;<br>        log.info(<span class="hljs-string">&quot;扩展消息转换器...&quot;</span>);<br>        <span class="hljs-comment">//创建消息转换器</span><br>        <span class="hljs-type">MappingJackson2HttpMessageConverter</span> <span class="hljs-variable">messageConverter</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">MappingJackson2HttpMessageConverter</span>();<br>        <span class="hljs-comment">//设置具体的对象映射器</span><br>        messageConverter.setObjectMapper(<span class="hljs-keyword">new</span> <span class="hljs-title class_">JacksonObjectMapper</span>());<br>        <span class="hljs-comment">//通过索引设置,让自己的转换器放在最前面,否则默认的jackson转换器会在最前面,用不上我们设置的转换器</span><br>        converters.add(<span class="hljs-number">0</span>, messageConverter);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="全局跨域处理"><a href="#全局跨域处理" class="headerlink" title="全局跨域处理"></a>全局跨域处理</h3><ul>
<li><h5 id="在WebConfig下作如下配置：（2023-08-22早）"><a href="#在WebConfig下作如下配置：（2023-08-22早）" class="headerlink" title="在WebConfig下作如下配置：（2023/08/22早）"></a>在WebConfig下作如下配置：（2023/08/22早）</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * Web配置类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@Configuration</span><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">WebConfig</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">WebMvcConfigurer</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 允许跨域请求</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> registry registry</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">addCorsMappings</span><span class="hljs-params">(CorsRegistry registry)</span> &#123;<br>        registry.addMapping(<span class="hljs-string">&quot;/**&quot;</span>)<br>                .allowCredentials(<span class="hljs-literal">true</span>)<br>                .allowedOrigins(<span class="hljs-string">&quot;http://localhost:7070&quot;</span>, <span class="hljs-string">&quot;http://localhost:3000&quot;</span>,<span class="hljs-string">&quot;http://120.55.62.195:7071&quot;</span>)<br>                .allowedMethods(<span class="hljs-string">&quot;GET&quot;</span>, <span class="hljs-string">&quot;POST&quot;</span>, <span class="hljs-string">&quot;DELETE&quot;</span>, <span class="hljs-string">&quot;PUT&quot;</span>)<br>                .maxAge(<span class="hljs-number">3600</span>);<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="只要是前端浏览器页面，调用后端接口，都应该在前后端做好跨域处理，不然就会遇到这种鸟问题，都不知道怎么解决：（2023-09-09晚）"><a href="#只要是前端浏览器页面，调用后端接口，都应该在前后端做好跨域处理，不然就会遇到这种鸟问题，都不知道怎么解决：（2023-09-09晚）" class="headerlink" title="只要是前端浏览器页面，调用后端接口，都应该在前后端做好跨域处理，不然就会遇到这种鸟问题，都不知道怎么解决：（2023/09/09晚）"></a>只要是前端浏览器页面，调用后端接口，都应该在<strong>前后端做好跨域处理</strong>，不然就会遇到这种鸟问题，都不知道怎么解决：（2023/09/09晚）</h5></li>
</ul>
<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230909174834655.png" alt="image-20230909174834655"></p>
<h3 id="Filter全局过滤器"><a href="#Filter全局过滤器" class="headerlink" title="Filter全局过滤器"></a>Filter全局过滤器</h3><ul>
<li><h5 id="年后，我学习了第一个完整的SpringBoot项目：瑞吉外卖，下面给出编写过滤器的一段代码：（2023-08-22早）"><a href="#年后，我学习了第一个完整的SpringBoot项目：瑞吉外卖，下面给出编写过滤器的一段代码：（2023-08-22早）" class="headerlink" title="年后，我学习了第一个完整的SpringBoot项目：瑞吉外卖，下面给出编写过滤器的一段代码：（2023/08/22早）"></a>年后，我学习了第一个完整的SpringBoot项目：瑞吉外卖，下面给出编写过滤器的一段代码：（2023/08/22早）</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author</span> 邓哈哈</span><br><span class="hljs-comment"> * 2023/1/13 10:19</span><br><span class="hljs-comment"> * Function:登录拦截</span><br><span class="hljs-comment"> * Version 1.0</span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 检查用户/员工是否完成登录</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@WebFilter(filterName = &quot;LoginCheckFilter&quot;)</span><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">LoginCheckFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Filter</span> &#123;<span class="hljs-comment">//验证是否登录</span><br>    <span class="hljs-comment">//路径匹配器,支持通配符</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">AntPathMatcher</span> <span class="hljs-variable">PATH_MATCHER</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">AntPathMatcher</span>();<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">doFilter</span><span class="hljs-params">(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)</span> <span class="hljs-keyword">throws</span> IOException, ServletException &#123;<br>        <span class="hljs-type">HttpServletRequest</span> <span class="hljs-variable">request</span> <span class="hljs-operator">=</span> (HttpServletRequest) servletRequest;<br>        <span class="hljs-type">HttpServletResponse</span> <span class="hljs-variable">response</span> <span class="hljs-operator">=</span> (HttpServletResponse) servletResponse;<br>        <span class="hljs-comment">//1.获取本次请求的URI</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">requestURI</span> <span class="hljs-operator">=</span> request.getRequestURI();<br><br>        <span class="hljs-comment">//定义不需要处理的请求路径</span><br>        String[] urls = <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>[]&#123;<br>                <span class="hljs-string">&quot;/employee/login&quot;</span>, <span class="hljs-comment">//登录时</span><br>                <span class="hljs-string">&quot;/employee/logout&quot;</span>, <span class="hljs-comment">//登出时</span><br>                <span class="hljs-string">&quot;/backend/**&quot;</span>,<br>                <span class="hljs-string">&quot;/front/**&quot;</span>,<br>                <span class="hljs-string">&quot;/user/sendMsg&quot;</span>,<br>                <span class="hljs-string">&quot;/user/login&quot;</span><br>        &#125;;<br><br>        <span class="hljs-comment">//2.判断本次请求是否需要处理</span><br>        <span class="hljs-type">boolean</span> <span class="hljs-variable">check</span> <span class="hljs-operator">=</span> check(urls, requestURI);<br><br>        <span class="hljs-comment">//3.如果不需要处理,则直接放行</span><br>        <span class="hljs-keyword">if</span> (check) &#123;<br>            log.info(<span class="hljs-string">&quot;本次请求不需要处理...&quot;</span>);<br>            filterChain.doFilter(request, response);<span class="hljs-comment">//放行请求</span><br>            <span class="hljs-keyword">return</span>;<br>        &#125;<br><br>        <span class="hljs-comment">// 4.1.需要处理的员工的请求,则判断登录状态,如果已经登录,则直接放行</span><br>        Long empId;<br>        <span class="hljs-keyword">if</span> ((empId = (Long) request.getSession().getAttribute(<span class="hljs-string">&quot;employee&quot;</span>)) != <span class="hljs-literal">null</span>) &#123;<span class="hljs-comment">//Session中存储着员工id(登录成功)</span><br>            log.info(<span class="hljs-string">&quot;该员工已登录,id为&#123;&#125;&quot;</span>, empId);<br><br>            BaseContext.setCurrentId(empId);<span class="hljs-comment">//ThreadLocal</span><br>            filterChain.doFilter(request, response);<span class="hljs-comment">//放行请求</span><br>            <span class="hljs-keyword">return</span>;<br>        &#125;<br><br>        <span class="hljs-comment">//4.2.需要处理的用户的请求,则判断登录状态,如果已经登录,则直接放行</span><br>        Long userId;<br>        <span class="hljs-keyword">if</span> ((userId = (Long) request.getSession().getAttribute(<span class="hljs-string">&quot;user&quot;</span>)) != <span class="hljs-literal">null</span>) &#123;<span class="hljs-comment">//Session中存储着用户id(登录成功)</span><br>            log.info(<span class="hljs-string">&quot;该用户已登录,id为&#123;&#125;&quot;</span>, userId);<br><br>            BaseContext.setCurrentId(userId);<span class="hljs-comment">//ThreadLocal</span><br><br>            filterChain.doFilter(request, response);<span class="hljs-comment">//放行请求</span><br>            <span class="hljs-keyword">return</span>;<br>        &#125;<br><br>        <span class="hljs-comment">//5.如果未登录,则返回登录结果,通过输出流方式向客户端页面响应数据</span><br>        log.info(<span class="hljs-string">&quot;该用户未登录...&quot;</span>);<br><br>        response.getWriter().write(JSON.toJSONString(R.error(<span class="hljs-string">&quot;NOTLOGIN&quot;</span>)));<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 路径匹配,检查本次请求是否需要放行</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> urls       :已定义的不需要处理的请求</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> requestURI :接收检查的请求</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">boolean</span> <span class="hljs-title function_">check</span><span class="hljs-params">(String[] urls, String requestURI)</span> &#123;<br>        <span class="hljs-keyword">for</span> (String url : urls) &#123;<br>            <span class="hljs-type">boolean</span> <span class="hljs-variable">match</span> <span class="hljs-operator">=</span> PATH_MATCHER.match(url, requestURI);<br>            <span class="hljs-keyword">if</span> (match) &#123;<span class="hljs-comment">//该请求不需要处理</span><br>                <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>            &#125;<br>        &#125;<br>        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<span class="hljs-comment">//该请求得处理</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   * 路径匹配,检查本次请求是否需要放行</span><br><span class="hljs-comment">   *</span><br><span class="hljs-comment">   * <span class="hljs-doctag">@param</span> urls       :已定义的不需要处理的请求</span><br><span class="hljs-comment">   * <span class="hljs-doctag">@param</span> requestURI :接收检查的请求</span><br><span class="hljs-comment">   * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">   */</span><br>  <span class="hljs-keyword">public</span> <span class="hljs-type">boolean</span> <span class="hljs-title function_">check</span><span class="hljs-params">(String[] urls, String requestURI)</span> &#123;<br>      <span class="hljs-keyword">for</span> (String url : urls) &#123;<br>          <span class="hljs-type">boolean</span> <span class="hljs-variable">match</span> <span class="hljs-operator">=</span> PATH_MATCHER.match(url, requestURI);<br>          <span class="hljs-keyword">if</span> (match) &#123;<span class="hljs-comment">//该请求不需要处理</span><br>              <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>          &#125;<br>      &#125;<br>      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<span class="hljs-comment">//该请求得处理</span><br>  &#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="这段代码的亮点包括以下几点："><a href="#这段代码的亮点包括以下几点：" class="headerlink" title="这段代码的亮点包括以下几点："></a>这段代码的亮点包括以下几点：</h5><ul>
<li>使用了@Log4j注解，简化了日志记录的操作。通过这个注解，可以直接使用log变量来记录日志。</li>
<li>使用了AntPathMatcher来匹配请求路径，支持通配符。这样可以减少对每个请求进行完全匹配的操作，提高了效率。</li>
<li>定义了不需要处理的请求路径，使用数组来存储。这样可以在数组中添加需要排除的路径，只对数组中未包含的路径进行处理。</li>
<li>使用check方法来判断当前请求是否需要处理。check方法会遍历请求路径数组，通过AntPathMatcher进行匹配，如果匹配成功则返回true，否则返回false。</li>
<li>如果当前请求需要处理，将继续调用FilterChain的doFilter方法，执行后续的过滤器或Servlet逻辑。如果不需要处理，则直接放行，不进行后续处理。</li>
</ul>
</li>
<li><h5 id="这样的设计可以在过滤器中对请求进行过滤，在需要处理的请求中执行相应的逻辑，而不需要处理的请求可以直接放行，提高了性能和效率。（2023-08-22早）"><a href="#这样的设计可以在过滤器中对请求进行过滤，在需要处理的请求中执行相应的逻辑，而不需要处理的请求可以直接放行，提高了性能和效率。（2023-08-22早）" class="headerlink" title="这样的设计可以在过滤器中对请求进行过滤，在需要处理的请求中执行相应的逻辑，而不需要处理的请求可以直接放行，提高了性能和效率。（2023/08/22早）"></a>这样的设计可以在过滤器中对请求进行过滤，在需要处理的请求中执行相应的逻辑，而不需要处理的请求可以直接放行，提高了性能和效率。（2023/08/22早）</h5></li>
</ul>
<h3 id="ThreadLocal"><a href="#ThreadLocal" class="headerlink" title="ThreadLocal"></a>ThreadLocal</h3><ul>
<li>从上面的代码中可以看到这样的业务流程：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 4.1.需要处理的员工的请求,则判断登录状态,如果已经登录,则直接放行</span><br>   Long empId;<br>   <span class="hljs-keyword">if</span> ((empId = (Long) request.getSession().getAttribute(<span class="hljs-string">&quot;employee&quot;</span>)) != <span class="hljs-literal">null</span>) &#123;<span class="hljs-comment">//Session中存储着员工id(登录成功)</span><br>       log.info(<span class="hljs-string">&quot;该员工已登录,id为&#123;&#125;&quot;</span>, empId);<br><br>       BaseContext.setCurrentId(empId);<span class="hljs-comment">//ThreadLocal</span><br>       filterChain.doFilter(request, response);<span class="hljs-comment">//放行请求</span><br>       <span class="hljs-keyword">return</span>;<br>   &#125;<br></code></pre></td></tr></table></figure>

<ul>
<li>这是将已登录员工的id封装在ThreadLocal中，为每一个使用到这个变量的线程创建了一个属于自己的副本</li>
<li>ThreadLocal 用作<strong>保存每个线程独享的对象</strong>，为每个线程都创建一个副本，这样每个线程都可以修改自己所拥有的副本, 而不会影响其他线程的副本，确保<strong>线程安全</strong></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">BaseContext</span> &#123;<br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ThreadLocal&lt;Long&gt; threadLocal = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ThreadLocal</span>();<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 设置当前线程的局部变量的值</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> id</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setCurrentId</span><span class="hljs-params">(Long id)</span> &#123;<br>        threadLocal.set(id);<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 返回当前线程对应的局部变量的值</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Long <span class="hljs-title function_">getCurrentId</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> threadLocal.get();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="公共字段自动填充"><a href="#公共字段自动填充" class="headerlink" title="公共字段自动填充"></a>公共字段自动填充</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author</span> 邓哈哈</span><br><span class="hljs-comment"> * 2023/1/16 11:12</span><br><span class="hljs-comment"> * Function:</span><br><span class="hljs-comment"> * Version 1.0</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@Configuration</span><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MyMetaObjectHandler</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">MetaObjectHandler</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 插入操作,自动填充</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> metaObject</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">insertFill</span><span class="hljs-params">(MetaObject metaObject)</span> &#123;<br>        log.info(<span class="hljs-string">&quot;公共字段自动填充...&quot;</span>);<br><br>        metaObject.setValue(<span class="hljs-string">&quot;createTime&quot;</span>, LocalDateTime.now());<br>        metaObject.setValue(<span class="hljs-string">&quot;updateTime&quot;</span>, LocalDateTime.now());<br>        metaObject.setValue(<span class="hljs-string">&quot;createUser&quot;</span>, BaseContext.getCurrentId());<br>        metaObject.setValue(<span class="hljs-string">&quot;updateUser&quot;</span>, BaseContext.getCurrentId());<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 更新操作,自动填充</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> metaObject</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">updateFill</span><span class="hljs-params">(MetaObject metaObject)</span> &#123;<br>        metaObject.setValue(<span class="hljs-string">&quot;updateTime&quot;</span>, LocalDateTime.now());<br>        metaObject.setValue(<span class="hljs-string">&quot;updateUser&quot;</span>, BaseContext.getCurrentId());<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure>

<ul>
<li><p>这段代码是一个实现了MyBatis的MetaObjectHandler接口的类。它的主要作用是<strong>实现自动填充功能</strong>，用于在插入和更新操作时自动填充某些公共字段的值</p>
</li>
<li><p>具体来说，这段代码通过<strong>重写insertFill和updateFill方法实现了自动填充功能</strong>：</p>
<ul>
<li><p>insertFill方法会在插入操作时被调用，自动填充一些字段的值。在这段代码中，它会设置createTime、updateTime、createUser和updateUser字段的值。其中，createTime和updateTime字段会被设置为当前时间，createUser和updateUser字段会被设置为当前用户的ID</p>
</li>
<li><p>updateFill方法会在更新操作时被调用，同样实现自动填充功能。在这段代码中，它会设置updateTime和updateUser字段的值，分别设置为当前时间和当前用户的ID</p>
</li>
</ul>
</li>
<li><h5 id="通过使用这个自定义的MyMetaObjectHandler类，可以实现在插入和更新操作时自动填充公共字段的值，避免了手动在每次操作中设置这些字段的麻烦，提高了开发效率（2023-08-22早）"><a href="#通过使用这个自定义的MyMetaObjectHandler类，可以实现在插入和更新操作时自动填充公共字段的值，避免了手动在每次操作中设置这些字段的麻烦，提高了开发效率（2023-08-22早）" class="headerlink" title="通过使用这个自定义的MyMetaObjectHandler类，可以实现在插入和更新操作时自动填充公共字段的值，避免了手动在每次操作中设置这些字段的麻烦，提高了开发效率（2023/08/22早）"></a>通过使用这个自定义的MyMetaObjectHandler类，可以实现在插入和更新操作时自动填充公共字段的值，避免了手动在每次操作中设置这些字段的麻烦，提高了开发效率（2023/08/22早）</h5></li>
</ul>
<h3 id="Lombok"><a href="#Lombok" class="headerlink" title="Lombok"></a>Lombok</h3><h3 id="commons-lang3"><a href="#commons-lang3" class="headerlink" title="commons-lang3"></a>commons-lang3</h3><h3 id="Gson"><a href="#Gson" class="headerlink" title="Gson"></a>Gson</h3><ul>
<li><a target="_blank" rel="noopener" href="https://juejin.cn/post/6844904154113146894?searchId=20230818150655BD9BB19565F023A9B0A5">求求你了，不要再自己实现这些逻辑了，开源工具类不香吗？ - 掘金 (juejin.cn)</a></li>
</ul>
<h3 id="基于基础类，开发一个VO类"><a href="#基于基础类，开发一个VO类" class="headerlink" title="基于基础类，开发一个VO类"></a>基于基础类，开发一个VO类</h3><ul>
<li>在开发过程，我们经常中使用基础类来开发VO类，是因为：<strong>（2023/09/14晚）</strong></li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs">基础类可以作为扩展点，用于定义VO类的共同特性和行为。<br>你可以在基础类中定义一些通用的属性和方法，然后在VO类中添加自定义属性和方法，以实现更具体的功能<br></code></pre></td></tr></table></figure>

<ul>
<li><p>最近在开发 MemoryChat 项目的过程中，遇到了这样的业务问题：</p>
</li>
<li><p>查询用户<strong>已加入的队伍</strong> / <strong>已创建的队伍</strong>，我想要展示队伍的 username（队长昵称），在team表中只有 userId字段（队长Id）</p>
</li>
<li><p>这就需要多表联查，封装携带队伍信息以及队长username的对象，并返回给前端</p>
</li>
<li><h5 id="那我们就开发一个teamVO类，用username字段代替userId字段，作为封装返回的对象："><a href="#那我们就开发一个teamVO类，用username字段代替userId字段，作为封装返回的对象：" class="headerlink" title="那我们就开发一个teamVO类，用username字段代替userId字段，作为封装返回的对象："></a>那我们就开发一个teamVO类，用username字段代替userId字段，作为封装返回的对象：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author</span> 邓哈哈</span><br><span class="hljs-comment"> * 2023/9/12 23:28</span><br><span class="hljs-comment"> * Function:</span><br><span class="hljs-comment"> * Version 1.0</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@Data</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TeamVO</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * id</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@TableId(type = IdType.ASSIGN_ID)</span><br>    <span class="hljs-keyword">private</span> Long id;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 队伍名称</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> String name;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 描述</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> String description;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 最大人数</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> Integer maxNum;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 队长昵称</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> String userName;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 队伍图片</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> String imgUrl;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 已加人数</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> Integer joinNum;<br>    <br>............................<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="根据相关查询条件，正确执行业务逻辑获取到teamList后，转换为teamVOList"><a href="#根据相关查询条件，正确执行业务逻辑获取到teamList后，转换为teamVOList" class="headerlink" title="根据相关查询条件，正确执行业务逻辑获取到teamList后，转换为teamVOList"></a>根据相关查询条件，正确执行业务逻辑获取到teamList后，转换为teamVOList</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 转换teamList为teamVOList</span><br>List&lt;TeamVO&gt; teamVOList = getTeamVOByTeam(teamList);<br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">  * 转换teamList为teamVOList</span><br><span class="hljs-comment">  *</span><br><span class="hljs-comment">  * <span class="hljs-doctag">@param</span> teamList teamList</span><br><span class="hljs-comment">  * <span class="hljs-doctag">@return</span> teamVOList</span><br><span class="hljs-comment">  */</span><br> <span class="hljs-keyword">public</span> List&lt;TeamVO&gt; <span class="hljs-title function_">getTeamVOByTeam</span><span class="hljs-params">(List&lt;Team&gt; teamList)</span> &#123;<br>     List&lt;TeamVO&gt; teamVOList = teamList.stream().map(team -&gt; &#123;<br>         <span class="hljs-type">Long</span> <span class="hljs-variable">userId</span> <span class="hljs-operator">=</span> team.getUserId();<br>         <span class="hljs-type">String</span> <span class="hljs-variable">userName</span> <span class="hljs-operator">=</span> userService.getById(userId).getUsername();<br>         <span class="hljs-type">TeamVO</span> <span class="hljs-variable">teamVO</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TeamVO</span>();<br><br>         teamVO.setId(team.getId());<br>         teamVO.setName(team.getName());<br>         teamVO.setDescription(team.getDescription());<br>         teamVO.setMaxNum(team.getMaxNum());<br>         teamVO.setUserName(userName);<br>         teamVO.setImgUrl(team.getImgUrl());<br>         teamVO.setJoinNum(team.getJoinNum());<br>         teamVO.setStatus(team.getStatus());<br>         teamVO.setExpireTime(team.getExpireTime());<br>         teamVO.setCreateTime(team.getCreateTime());<br>         teamVO.setUpdateTime(team.getUpdateTime());<br>         teamVO.setIsDelete(team.getIsDelete());<br><br>         <span class="hljs-keyword">return</span> teamVO;<br>     &#125;).collect(Collectors.toList());<br><br>     <span class="hljs-keyword">return</span> teamVOList;<br> &#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="就这样，我们将队伍信息和队长-username-封装在了-teamVOList-对象中，成功返回到了前端"><a href="#就这样，我们将队伍信息和队长-username-封装在了-teamVOList-对象中，成功返回到了前端" class="headerlink" title="就这样，我们将队伍信息和队长 username 封装在了 teamVOList 对象中，成功返回到了前端"></a>就这样，我们将队伍信息和队长 username 封装在了 teamVOList 对象中，成功返回到了前端</h5></li>
<li><p>现在，我们可以看到队伍的<strong>队长信息</strong>了：<strong>（2023/09/14晚）</strong></p>
</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230914222548059.png" alt="image-20230914222548059"></p>
<h2 id="踩坑记录"><a href="#踩坑记录" class="headerlink" title="踩坑记录"></a>踩坑记录</h2><ul>
<li><h5 id="每当我兴致勃勃地启动项目，准备大展身手的时候，项目启动窗口总会弹出冰冷的报错信息"><a href="#每当我兴致勃勃地启动项目，准备大展身手的时候，项目启动窗口总会弹出冰冷的报错信息" class="headerlink" title="每当我兴致勃勃地启动项目，准备大展身手的时候，项目启动窗口总会弹出冰冷的报错信息"></a>每当我兴致勃勃地启动项目，准备大展身手的时候，项目启动窗口总会弹出冰冷的报错信息</h5></li>
<li><h5 id="这里列举了：我遇到过的所有启动项目报错的解决办法"><a href="#这里列举了：我遇到过的所有启动项目报错的解决办法" class="headerlink" title="这里列举了：我遇到过的所有启动项目报错的解决办法"></a>这里列举了：我遇到过的所有启动项目报错的解决办法</h5></li>
</ul>
<h3 id="XXXMapper包扫描不到"><a href="#XXXMapper包扫描不到" class="headerlink" title="XXXMapper包扫描不到"></a>XXXMapper包扫描不到</h3><ul>
<li><h5 id="当你看到这样的报错，你会怎么解决呢："><a href="#当你看到这样的报错，你会怎么解决呢：" class="headerlink" title="当你看到这样的报错，你会怎么解决呢："></a>当你看到这样的报错，你会怎么解决呢：</h5></li>
</ul>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dart">Unsatisfied dependency expressed through field <span class="hljs-string">&#x27;baseMapper&#x27;</span>; nested exception <span class="hljs-keyword">is</span> org.springframework.beans.<span class="hljs-keyword">factory</span>.NoSuchBeanDefinitionException: No qualifying bean of type <span class="hljs-string">&#x27;com.memory.memoryiconbackend.mapper.WallpaperMapper&#x27;</span> available: expected at least <span class="hljs-number">1</span> bean which qualifies <span class="hljs-keyword">as</span> autowire candidate. Dependency annotations: &#123;<span class="hljs-meta">@org</span>.springframework.beans.<span class="hljs-keyword">factory</span>.annotation.Autowired(<span class="hljs-keyword">required</span>=<span class="hljs-keyword">true</span>)&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="这个报错信息大致意思是，未扫描到你的XXXMapper包，项目启动失败"><a href="#这个报错信息大致意思是，未扫描到你的XXXMapper包，项目启动失败" class="headerlink" title="这个报错信息大致意思是，未扫描到你的XXXMapper包，项目启动失败"></a>这个报错信息大致意思是，未扫描到你的XXXMapper包，项目启动失败</h5></li>
<li><h5 id="这个问题可谓最常见了，刚刚我就又被这个问题恶心到了，网上查了半天，感觉他们都是一知半解"><a href="#这个问题可谓最常见了，刚刚我就又被这个问题恶心到了，网上查了半天，感觉他们都是一知半解" class="headerlink" title="这个问题可谓最常见了，刚刚我就又被这个问题恶心到了，网上查了半天，感觉他们都是一知半解"></a>这个问题可谓最常见了，刚刚我就又被这个问题恶心到了，网上查了半天，感觉他们都是一知半解</h5></li>
<li><h5 id="那么我是怎么解决这个问题的呢？思路如下："><a href="#那么我是怎么解决这个问题的呢？思路如下：" class="headerlink" title="那么我是怎么解决这个问题的呢？思路如下："></a>那么我是怎么解决这个问题的呢？思路如下：</h5></li>
</ul>
<h4 id="XXXMapper-xml配置错误"><a href="#XXXMapper-xml配置错误" class="headerlink" title="XXXMapper.xml配置错误"></a>XXXMapper.xml配置错误</h4><ul>
<li><h5 id="检查resource下的XXXMapper-xml配置，检查实体类扫描和mapper扫描路径是否正确："><a href="#检查resource下的XXXMapper-xml配置，检查实体类扫描和mapper扫描路径是否正确：" class="headerlink" title="检查resource下的XXXMapper.xml配置，检查实体类扫描和mapper扫描路径是否正确："></a>检查resource下的XXXMapper.xml配置，检查实体类扫描和mapper扫描路径是否正确：</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230801180028233.png" alt="image-20230801180028233"></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=<span class="hljs-string">&quot;1.0&quot;</span> encoding=<span class="hljs-string">&quot;UTF-8&quot;</span>?&gt;</span><br><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">mapper</span></span><br><span class="hljs-meta">        <span class="hljs-keyword">PUBLIC</span> <span class="hljs-string">&quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;</span></span><br><span class="hljs-meta">        <span class="hljs-string">&quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">mapper</span> <span class="hljs-attr">namespace</span>=<span class="hljs-string">&quot;com.memory.memoryiconbackend.mapper.WallpaperMapper&quot;</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">resultMap</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;BaseResultMap&quot;</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;com.memory.memoryiconbackend.model.Wallpaper&quot;</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">result</span> <span class="hljs-attr">property</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">column</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">jdbcType</span>=<span class="hljs-string">&quot;VARCHAR&quot;</span>/&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">result</span> <span class="hljs-attr">property</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">column</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">jdbcType</span>=<span class="hljs-string">&quot;VARCHAR&quot;</span>/&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">result</span> <span class="hljs-attr">property</span>=<span class="hljs-string">&quot;url&quot;</span> <span class="hljs-attr">column</span>=<span class="hljs-string">&quot;url&quot;</span> <span class="hljs-attr">jdbcType</span>=<span class="hljs-string">&quot;VARCHAR&quot;</span>/&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">result</span> <span class="hljs-attr">property</span>=<span class="hljs-string">&quot;type&quot;</span> <span class="hljs-attr">column</span>=<span class="hljs-string">&quot;type&quot;</span> <span class="hljs-attr">jdbcType</span>=<span class="hljs-string">&quot;VARCHAR&quot;</span>/&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">result</span> <span class="hljs-attr">property</span>=<span class="hljs-string">&quot;tags&quot;</span> <span class="hljs-attr">column</span>=<span class="hljs-string">&quot;tags&quot;</span> <span class="hljs-attr">jdbcType</span>=<span class="hljs-string">&quot;VARCHAR&quot;</span>/&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">result</span> <span class="hljs-attr">property</span>=<span class="hljs-string">&quot;createTime&quot;</span> <span class="hljs-attr">column</span>=<span class="hljs-string">&quot;create_time&quot;</span> <span class="hljs-attr">jdbcType</span>=<span class="hljs-string">&quot;VARCHAR&quot;</span>/&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">result</span> <span class="hljs-attr">property</span>=<span class="hljs-string">&quot;updateTime&quot;</span> <span class="hljs-attr">column</span>=<span class="hljs-string">&quot;update_time&quot;</span> <span class="hljs-attr">jdbcType</span>=<span class="hljs-string">&quot;VARCHAR&quot;</span>/&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">result</span> <span class="hljs-attr">property</span>=<span class="hljs-string">&quot;isDelete&quot;</span> <span class="hljs-attr">column</span>=<span class="hljs-string">&quot;is_delete&quot;</span> <span class="hljs-attr">jdbcType</span>=<span class="hljs-string">&quot;VARCHAR&quot;</span>/&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">result</span> <span class="hljs-attr">property</span>=<span class="hljs-string">&quot;userId&quot;</span> <span class="hljs-attr">column</span>=<span class="hljs-string">&quot;user_id&quot;</span> <span class="hljs-attr">jdbcType</span>=<span class="hljs-string">&quot;VARCHAR&quot;</span>/&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">resultMap</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">sql</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;Base_Column_List&quot;</span>&gt;</span><br>        id,name,url,<br>        type,tags,create_time,<br>        update_time,is_delete,user_id<br>    <span class="hljs-tag">&lt;/<span class="hljs-name">sql</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">mapper</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="确保XXXMapper包的扫描路径正确后，再继续排查："><a href="#确保XXXMapper包的扫描路径正确后，再继续排查：" class="headerlink" title="确保XXXMapper包的扫描路径正确后，再继续排查："></a>确保XXXMapper包的扫描路径正确后，再继续排查：</h5></li>
</ul>
<h4 id="XXXMapper上添加-Mapper注解"><a href="#XXXMapper上添加-Mapper注解" class="headerlink" title="XXXMapper上添加@Mapper注解"></a>XXXMapper上添加@Mapper注解</h4><ul>
<li><h5 id="检查XXXMapper上是否添加了-Mapper注解："><a href="#检查XXXMapper上是否添加了-Mapper注解：" class="headerlink" title="检查XXXMapper上是否添加了@Mapper注解："></a>检查XXXMapper上是否添加了@Mapper注解：</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230801180147709.png" alt="image-20230801180147709"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Mapper</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title class_">WallpaperMapper</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">BaseMapper</span>&lt;Wallpaper&gt; &#123;<br><br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="如果这两部还没有解决你的问题，请一定继续往下看："><a href="#如果这两部还没有解决你的问题，请一定继续往下看：" class="headerlink" title="如果这两部还没有解决你的问题，请一定继续往下看："></a>如果这两部还没有解决你的问题，请一定继续往下看：</h5></li>
</ul>
<h4 id="开启-MapperScan注解"><a href="#开启-MapperScan注解" class="headerlink" title="开启@MapperScan注解"></a>开启@MapperScan注解</h4><ul>
<li><h5 id="MapperScan注解是干嘛的呢？它是用来在项目启动后，扫描你的XXXMapper所在路径，用法如下："><a href="#MapperScan注解是干嘛的呢？它是用来在项目启动后，扫描你的XXXMapper所在路径，用法如下：" class="headerlink" title="@MapperScan注解是干嘛的呢？它是用来在项目启动后，扫描你的XXXMapper所在路径，用法如下："></a>@MapperScan注解是干嘛的呢？它是用来在项目启动后，扫描你的XXXMapper所在路径，用法如下：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs java"><br><span class="hljs-meta">@SpringBootApplication</span><br><span class="hljs-meta">@MapperScan(&quot;com.memory.memoryiconbackend.mapper.WallpaperMapper&quot;)</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MemoryIconBackendApplication</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        SpringApplication.run(MemoryIconBackendApplication.class, args);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="那这个注解跟上面提到的-Mapper注解，功能不是一样的吗？都是将XXXMapper标注为一个Bean，交给Spring管理"><a href="#那这个注解跟上面提到的-Mapper注解，功能不是一样的吗？都是将XXXMapper标注为一个Bean，交给Spring管理" class="headerlink" title="那这个注解跟上面提到的@Mapper注解，功能不是一样的吗？都是将XXXMapper标注为一个Bean，交给Spring管理"></a>那这个注解跟上面提到的@Mapper注解，功能不是一样的吗？都是将XXXMapper标注为一个Bean，交给Spring管理</h5></li>
<li><h5 id="没错，这两个注解的作用是可以说是一摸一样的，无非就是写的位置不一样"><a href="#没错，这两个注解的作用是可以说是一摸一样的，无非就是写的位置不一样" class="headerlink" title="没错，这两个注解的作用是可以说是一摸一样的，无非就是写的位置不一样"></a>没错，这两个注解的作用是可以说是一摸一样的，无非就是写的位置不一样</h5></li>
<li><h5 id="正是因为这两个注解作用是一样的，所以在开发过程中，这两个注解写一个就行，而且只能写一个，否则会报错"><a href="#正是因为这两个注解作用是一样的，所以在开发过程中，这两个注解写一个就行，而且只能写一个，否则会报错" class="headerlink" title="正是因为这两个注解作用是一样的，所以在开发过程中，这两个注解写一个就行，而且只能写一个，否则会报错"></a>正是因为这两个注解作用是一样的，所以在开发过程中，这两个注解写一个就行，而且只能写一个，否则会报错</h5></li>
<li><h5 id="网上总会有蠢蛋，说在XXXMapper上，添加了-Mapper注解之后，一定不要忘了在启动类上添加-MapperScan注解"><a href="#网上总会有蠢蛋，说在XXXMapper上，添加了-Mapper注解之后，一定不要忘了在启动类上添加-MapperScan注解" class="headerlink" title="网上总会有蠢蛋，说在XXXMapper上，添加了@Mapper注解之后，一定不要忘了在启动类上添加@MapperScan注解"></a>网上总会有蠢蛋，说在XXXMapper上，添加了@Mapper注解之后，一定不要忘了在启动类上添加@MapperScan注解</h5></li>
<li><h5 id="这种方法肯定解决不了问题，是大错特错的"><a href="#这种方法肯定解决不了问题，是大错特错的" class="headerlink" title="这种方法肯定解决不了问题，是大错特错的"></a>这种方法肯定解决不了问题，是大错特错的</h5></li>
<li><h5 id="所以，如果你已经在XXXMapper上添加了-Mapper注解，一定记得删除启动类上的-MapperScan注解"><a href="#所以，如果你已经在XXXMapper上添加了-Mapper注解，一定记得删除启动类上的-MapperScan注解" class="headerlink" title="所以，如果你已经在XXXMapper上添加了@Mapper注解，一定记得删除启动类上的@MapperScan注解"></a>所以，如果你已经在XXXMapper上添加了@Mapper注解，一定记得删除启动类上的@MapperScan注解</h5></li>
<li><h5 id="如果到这里，你已经按照上面的方法解决了问题，成功启动了项目，恭喜你；如果仍旧报错，请继续往下看："><a href="#如果到这里，你已经按照上面的方法解决了问题，成功启动了项目，恭喜你；如果仍旧报错，请继续往下看：" class="headerlink" title="如果到这里，你已经按照上面的方法解决了问题，成功启动了项目，恭喜你；如果仍旧报错，请继续往下看："></a>如果到这里，你已经按照上面的方法解决了问题，成功启动了项目，恭喜你；如果仍旧报错，请继续往下看：</h5></li>
</ul>
<h4 id="MybatisPlusConfig配置"><a href="#MybatisPlusConfig配置" class="headerlink" title="MybatisPlusConfig配置"></a>MybatisPlusConfig配置</h4><ul>
<li><h5 id="我们在项目中，导入了MybatisPlus依赖之后，总会写一个MybatisPlusConfig的分页配置："><a href="#我们在项目中，导入了MybatisPlus依赖之后，总会写一个MybatisPlusConfig的分页配置：" class="headerlink" title="我们在项目中，导入了MybatisPlus依赖之后，总会写一个MybatisPlusConfig的分页配置："></a>我们在项目中，导入了MybatisPlus依赖之后，总会写一个MybatisPlusConfig的分页配置：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * mybatis-plus 分页配置类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@Configuration</span><br><span class="hljs-meta">@MapperScan(&quot;com.memory.memoryiconbackend.mapper.WallpaperMapper&quot;)</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MybatisPlusConfig</span> &#123;<br>    <span class="hljs-meta">@Bean</span><br>    <span class="hljs-keyword">public</span> MybatisPlusInterceptor <span class="hljs-title function_">mybatisPlusInterceptor</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-type">MybatisPlusInterceptor</span> <span class="hljs-variable">interceptor</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">MybatisPlusInterceptor</span>();<br>        interceptor.addInnerInterceptor(<span class="hljs-keyword">new</span> <span class="hljs-title class_">PaginationInnerInterceptor</span>(DbType.MYSQL));<br>        <span class="hljs-keyword">return</span> interceptor;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="如果你的问题没有解决，一定是因为在这个配置类上边，写上了-MapperScan注解："><a href="#如果你的问题没有解决，一定是因为在这个配置类上边，写上了-MapperScan注解：" class="headerlink" title="如果你的问题没有解决，一定是因为在这个配置类上边，写上了@MapperScan注解："></a>如果你的问题没有解决，一定是因为在这个配置类上边，写上了@MapperScan注解：</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230801182811187.png" alt="image-20230801182811187"></p>
<ul>
<li><h5 id="而这个注解的作用，跟启动类上的-MapperScan注解的作用是一模一样的，删除它就好了"><a href="#而这个注解的作用，跟启动类上的-MapperScan注解的作用是一模一样的，删除它就好了" class="headerlink" title="而这个注解的作用，跟启动类上的@MapperScan注解的作用是一模一样的，删除它就好了"></a>而这个注解的作用，跟启动类上的@MapperScan注解的作用是一模一样的，删除它就好了</h5></li>
</ul>
<h4 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h4><ul>
<li><h5 id="如果你已经在XXXMapper上添加了-Mapper注解，请把启动类和MybatisPlusConfig配置类上的-MapperScan注解删除"><a href="#如果你已经在XXXMapper上添加了-Mapper注解，请把启动类和MybatisPlusConfig配置类上的-MapperScan注解删除" class="headerlink" title="如果你已经在XXXMapper上添加了@Mapper注解，请把启动类和MybatisPlusConfig配置类上的@MapperScan注解删除"></a>如果你已经在XXXMapper上添加了@Mapper注解，请把启动类和MybatisPlusConfig配置类上的@MapperScan注解删除</h5></li>
<li><h5 id="如果你已经在启动类和MybatisPlusConfig配置类上添加了-MapperScan注解，请把XXXMapper上的-Mapper注解删除"><a href="#如果你已经在启动类和MybatisPlusConfig配置类上添加了-MapperScan注解，请把XXXMapper上的-Mapper注解删除" class="headerlink" title="如果你已经在启动类和MybatisPlusConfig配置类上添加了@MapperScan注解，请把XXXMapper上的@Mapper注解删除"></a>如果你已经在启动类和MybatisPlusConfig配置类上添加了@MapperScan注解，请把XXXMapper上的@Mapper注解删除</h5></li>
<li><h5 id="希望这篇文章对你有帮助，感谢您的支持！😁"><a href="#希望这篇文章对你有帮助，感谢您的支持！😁" class="headerlink" title="希望这篇文章对你有帮助，感谢您的支持！😁"></a>希望这篇文章对你有帮助，感谢您的支持！😁</h5></li>
</ul>
<h3 id="类文件版本不匹配"><a href="#类文件版本不匹配" class="headerlink" title="类文件版本不匹配"></a>类文件版本不匹配</h3><ul>
<li><h5 id="如果在启动项目时，出现了这样的报错，你会怎么解决呢："><a href="#如果在启动项目时，出现了这样的报错，你会怎么解决呢：" class="headerlink" title="如果在启动项目时，出现了这样的报错，你会怎么解决呢："></a>如果在启动项目时，出现了这样的报错，你会怎么解决呢：</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230802082050802.png" alt="image-20230802082050802"></p>
<ul>
<li><h5 id="引起这样报错的原因只有一种：类文件版本不匹配，即项目里导入的依赖版本不兼容"><a href="#引起这样报错的原因只有一种：类文件版本不匹配，即项目里导入的依赖版本不兼容" class="headerlink" title="引起这样报错的原因只有一种：类文件版本不匹配，即项目里导入的依赖版本不兼容"></a>引起这样报错的原因只有一种：类文件版本不匹配，即项目里导入的依赖版本不兼容</h5></li>
</ul>
<h4 id="Mybatis版本-和-SpringBoot版本不兼容"><a href="#Mybatis版本-和-SpringBoot版本不兼容" class="headerlink" title="Mybatis版本 和 SpringBoot版本不兼容"></a>Mybatis版本 和 SpringBoot版本不兼容</h4><ul>
<li><h5 id="查看上方报错信息，很显然是XXXMapper包扫描失败了，这就是Mybatis版本-和-SpringBoot版本不兼容的问题"><a href="#查看上方报错信息，很显然是XXXMapper包扫描失败了，这就是Mybatis版本-和-SpringBoot版本不兼容的问题" class="headerlink" title="查看上方报错信息，很显然是XXXMapper包扫描失败了，这就是Mybatis版本 和 SpringBoot版本不兼容的问题"></a>查看上方报错信息，很显然是XXXMapper包扫描失败了，这就是Mybatis版本 和 SpringBoot版本不兼容的问题</h5></li>
<li><h5 id="如此配置：-2023-08-02早"><a href="#如此配置：-2023-08-02早" class="headerlink" title="如此配置：(2023/08/02早)"></a>如此配置：(2023/08/02早)</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.mybatis.spring.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mybatis-spring-boot-starter<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.3.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>      <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">parent</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.7.14<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">relativePath</span>/&gt;</span> <span class="hljs-comment">&lt;!-- lookup parent from repository --&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">parent</span>&gt;</span><br></code></pre></td></tr></table></figure>

<h4 id="Jdk版本-和-SpringBoot版本不兼容"><a href="#Jdk版本-和-SpringBoot版本不兼容" class="headerlink" title="Jdk版本 和 SpringBoot版本不兼容"></a>Jdk版本 和 SpringBoot版本不兼容</h4><ul>
<li><h5 id="当你启动项目时，看到了这样的报错："><a href="#当你启动项目时，看到了这样的报错：" class="headerlink" title="当你启动项目时，看到了这样的报错："></a>当你启动项目时，看到了这样的报错：</h5></li>
</ul>
<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230802182601591.png" alt="image-20230802182601591"></p>
<ul>
<li><h5 id="这是由于Jdk版本-和-SpringBoot版本不兼容导致的"><a href="#这是由于Jdk版本-和-SpringBoot版本不兼容导致的" class="headerlink" title="这是由于Jdk版本 和 SpringBoot版本不兼容导致的"></a>这是由于Jdk版本 和 SpringBoot版本不兼容导致的</h5></li>
<li><h5 id="JDK版本不兼容，还并且可能导致其他配置构建失败："><a href="#JDK版本不兼容，还并且可能导致其他配置构建失败：" class="headerlink" title="JDK版本不兼容，还并且可能导致其他配置构建失败："></a>JDK版本不兼容，还并且可能导致其他配置构建失败：</h5></li>
</ul>
<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230802182701312.png" alt="image-20230802182701312"></p>
<ul>
<li><h5 id="这是我的SpringBoot坐标依赖："><a href="#这是我的SpringBoot坐标依赖：" class="headerlink" title="这是我的SpringBoot坐标依赖："></a>这是我的SpringBoot坐标依赖：</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">parent</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.7.9<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">relativePath</span>/&gt;</span> <span class="hljs-comment">&lt;!-- lookup parent from repository --&gt;</span><br>   <span class="hljs-tag">&lt;/<span class="hljs-name">parent</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="按照提示，升级JDK版本到1-8以上即可解决问题"><a href="#按照提示，升级JDK版本到1-8以上即可解决问题" class="headerlink" title="按照提示，升级JDK版本到1.8以上即可解决问题"></a>按照提示，升级JDK版本到1.8以上即可解决问题</h5></li>
</ul>
<h3 id="相关依赖未导入"><a href="#相关依赖未导入" class="headerlink" title="相关依赖未导入"></a>相关依赖未导入</h3><h4 id="MySQL相关依赖未导入"><a href="#MySQL相关依赖未导入" class="headerlink" title="MySQL相关依赖未导入"></a>MySQL相关依赖未导入</h4><ul>
<li><h5 id="今天在做-PicMemories-项目过程中，启动项目时，出现了以下报错："><a href="#今天在做-PicMemories-项目过程中，启动项目时，出现了以下报错：" class="headerlink" title="今天在做 PicMemories 项目过程中，启动项目时，出现了以下报错："></a>今天在做 PicMemories 项目过程中，启动项目时，出现了以下报错：</h5></li>
</ul>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean <span class="hljs-keyword">with</span> <span class="hljs-type">name</span> <span class="hljs-string">&#x27;downloadServiceImpl&#x27;</span>: Unsatisfied dependency expressed through field <span class="hljs-string">&#x27;baseMapper&#x27;</span>; nested <span class="hljs-keyword">exception</span> <span class="hljs-keyword">is</span> org.springframework.beans.factory.BeanCreationException: Error creating bean <span class="hljs-keyword">with</span> <span class="hljs-type">name</span> <span class="hljs-string">&#x27;downloadMapper&#x27;</span> defined <span class="hljs-keyword">in</span> file [D:\Project\星球项目\PicMemories\target\classes\com\memory\picmemories\mapper\DownloadMapper.<span class="hljs-keyword">class</span>]: Cannot resolve reference <span class="hljs-keyword">to</span> bean <span class="hljs-string">&#x27;sqlSessionTemplate&#x27;</span> <span class="hljs-keyword">while</span> setting bean property <span class="hljs-string">&#x27;sqlSessionTemplate&#x27;</span>; nested <span class="hljs-keyword">exception</span> <span class="hljs-keyword">is</span> org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean <span class="hljs-keyword">with</span> <span class="hljs-type">name</span> <span class="hljs-string">&#x27;dataSourceScriptDatabaseInitializer&#x27;</span> defined <span class="hljs-keyword">in</span> <span class="hljs-keyword">class</span> <span class="hljs-type">path</span> resource [org/springframework/boot/autoconfigure/<span class="hljs-keyword">sql</span>/init/DataSourceInitializationConfiguration.<span class="hljs-keyword">class</span>]: Unsatisfied dependency expressed through <span class="hljs-keyword">method</span> <span class="hljs-string">&#x27;dataSourceScriptDatabaseInitializer&#x27;</span> parameter <span class="hljs-number">0</span>; nested <span class="hljs-keyword">exception</span> <span class="hljs-keyword">is</span> org.springframework.beans.factory.BeanCreationException: Error creating bean <span class="hljs-keyword">with</span> <span class="hljs-type">name</span> <span class="hljs-string">&#x27;dataSource&#x27;</span> defined <span class="hljs-keyword">in</span> <span class="hljs-keyword">class</span> <span class="hljs-type">path</span> resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.<span class="hljs-keyword">class</span>]: Bean instantiation via factory <span class="hljs-keyword">method</span> failed; nested <span class="hljs-keyword">exception</span> <span class="hljs-keyword">is</span> org.springframework.beans.BeanInstantiationException: Failed <span class="hljs-keyword">to</span> instantiate [com.zaxxer.hikari.HikariDataSource]: Factory <span class="hljs-keyword">method</span> <span class="hljs-string">&#x27;dataSource&#x27;</span> threw <span class="hljs-keyword">exception</span>; nested <span class="hljs-keyword">exception</span> <span class="hljs-keyword">is</span> java.lang.IllegalStateException: Cannot <span class="hljs-keyword">load</span> driver <span class="hljs-keyword">class</span>: com.mysql.cj.jdbc.Driver<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="经排查，发现是MySQL相关依赖导入错了，我导入的错误依赖如下："><a href="#经排查，发现是MySQL相关依赖导入错了，我导入的错误依赖如下：" class="headerlink" title="经排查，发现是MySQL相关依赖导入错了，我导入的错误依赖如下："></a>经排查，发现是MySQL相关依赖导入错了，我导入的错误依赖如下：</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.microsoft.sqlserver<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mssql-jdbc<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>runtime<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="正确的依赖应该为："><a href="#正确的依赖应该为：" class="headerlink" title="正确的依赖应该为："></a>正确的依赖应该为：</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.mysql<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mysql-connector-j<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>runtime<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span><br>   <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="为什么会出现这样的错误呢？是因为我在构建项目时，选择导入以下依赖中，发生了错误："><a href="#为什么会出现这样的错误呢？是因为我在构建项目时，选择导入以下依赖中，发生了错误：" class="headerlink" title="为什么会出现这样的错误呢？是因为我在构建项目时，选择导入以下依赖中，发生了错误："></a>为什么会出现这样的错误呢？是因为我在构建项目时，选择导入以下依赖中，发生了错误：</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230802183420381.png" alt="image-20230802183420381"></p>
<ul>
<li><h5 id="这里一定要选择MySQL-Driver，而不是MySQL-Server-Driver，否则就会导入错误的依赖而引发报错（2023-08-02午）"><a href="#这里一定要选择MySQL-Driver，而不是MySQL-Server-Driver，否则就会导入错误的依赖而引发报错（2023-08-02午）" class="headerlink" title="这里一定要选择MySQL Driver，而不是MySQL Server Driver，否则就会导入错误的依赖而引发报错（2023/08/02午）"></a>这里一定要选择MySQL Driver，而不是MySQL Server Driver，否则就会导入错误的依赖而引发报错（2023/08/02午）</h5></li>
</ul>
<h3 id="快速生成-Swagger-Knif4j-接口文档"><a href="#快速生成-Swagger-Knif4j-接口文档" class="headerlink" title="快速生成 Swagger + Knif4j 接口文档"></a>快速生成 <code>Swagger</code> + <code>Knif4j</code> 接口文档</h3><ul>
<li><p>昨天遇到的问题，今天总算解决了，废话少说，上案例：</p>
</li>
<li><p>在开发 Memory-icon 和 PicMemories 项目时，都遇到了这个问题：明明Knif4j配置无误，接口文档访问却报404错误：</p>
</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230802184955677.png" alt="image-20230802184955677"></p>
<ul>
<li><h5 id="Knif4j官方文档：快速开始-Knife4j-xiaominfo-com"><a href="#Knif4j官方文档：快速开始-Knife4j-xiaominfo-com" class="headerlink" title="Knif4j官方文档：快速开始 | Knife4j (xiaominfo.com)"></a>Knif4j官方文档：<a target="_blank" rel="noopener" href="https://doc.xiaominfo.com/docs/quick-start">快速开始 | Knife4j (xiaominfo.com)</a></h5></li>
<li><p>按照官方文档，我们可以清楚地看到不同版本的 SpringBoot 导入Swagger + Knif4j 接口文档的方式是不一样的</p>
</li>
<li><p><code>Spring Boot</code> 版本在 <code>2.4.0 </code>~ <code>3.0.0</code>之间，以我为例，我的Spring Boot 版本是2.7.9</p>
</li>
<li><p>那么使用 Swagger + Kni4j 自动生成接口文档的步骤如下：</p>
<ul>
<li><h5 id="导入依赖坐标"><a href="#导入依赖坐标" class="headerlink" title="导入依赖坐标"></a>导入依赖坐标</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.github.xiaoymin<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>knife4j-openapi2-spring-boot-starter<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>4.0.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>      <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="在appilcation-yaml中导入配置："><a href="#在appilcation-yaml中导入配置：" class="headerlink" title="在appilcation.yaml中导入配置："></a>在appilcation.yaml中导入配置：</h5></li>
</ul>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">knife4j:</span><br>  <span class="hljs-attr">enable:</span> <span class="hljs-literal">true</span><br>  <span class="hljs-attr">openapi:</span><br>    <span class="hljs-attr">title:</span> <span class="hljs-string">PicMemories</span> <span class="hljs-string">接口文档</span><br>    <span class="hljs-attr">description:</span> <span class="hljs-string">PicMemories</span> <span class="hljs-string">壁纸分享小程序</span><br>    <span class="hljs-attr">concat:</span> <span class="hljs-number">3348407547</span><span class="hljs-string">@qq.com</span><br>    <span class="hljs-attr">url:</span> <span class="hljs-string">https://deng-2022.gitee.io/blog/</span><br>    <span class="hljs-attr">version:</span> <span class="hljs-number">1.0</span><br>    <span class="hljs-attr">license:</span> <span class="hljs-string">Apache</span> <span class="hljs-number">2.0</span><br>    <span class="hljs-attr">group:</span><br>      <span class="hljs-attr">test1:</span><br>       <span class="hljs-attr">group-name:</span> <span class="hljs-string">壁纸分享</span><br></code></pre></td></tr></table></figure></li>
<li><h5 id="完毕，已经能够正常访问到接口文档了：http-localhost-8084-api-doc-html（2023-08-02晚）"><a href="#完毕，已经能够正常访问到接口文档了：http-localhost-8084-api-doc-html（2023-08-02晚）" class="headerlink" title="完毕，已经能够正常访问到接口文档了：http://localhost:8084/api/doc.html（2023/08/02晚）"></a>完毕，已经能够正常访问到接口文档了：<a href="">http://localhost:8084/api/doc.html</a>（2023/08/02晚）</h5></li>
</ul>
<h3 id="执行SQL找不到字段"><a href="#执行SQL找不到字段" class="headerlink" title="执行SQL找不到字段"></a>执行SQL找不到字段</h3><ul>
<li><h5 id="如果在执行SQL时，出现了以下问题："><a href="#如果在执行SQL时，出现了以下问题：" class="headerlink" title="如果在执行SQL时，出现了以下问题："></a>如果在执行SQL时，出现了以下问题：</h5></li>
</ul>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-literal">Unknown</span> <span class="hljs-keyword">column</span> <span class="hljs-string">&#x27;user_id&#x27;</span> <span class="hljs-keyword">in</span> <span class="hljs-string">&#x27;field list&#x27;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230803082954240.png" alt="image-20230803082954240"></p>
<ul>
<li><h5 id="报错信息显示，找不到字段user-id，解决思路如下："><a href="#报错信息显示，找不到字段user-id，解决思路如下：" class="headerlink" title="报错信息显示，找不到字段user_id，解决思路如下："></a>报错信息显示，找不到字段user_id，解决思路如下：</h5><ul>
<li>首先，确定这个对应数据库中有这个字段user_id</li>
<li>其次，确保实体类属性和表中字段映射无误</li>
<li>最后，检查数据库配置是否正确</li>
</ul>
</li>
<li><h5 id="我就栽在最后一步上了，数据库连接到别的表了，怪不得找不到相应字段，折磨了我一晚上（2023-08-03早）"><a href="#我就栽在最后一步上了，数据库连接到别的表了，怪不得找不到相应字段，折磨了我一晚上（2023-08-03早）" class="headerlink" title="我就栽在最后一步上了，数据库连接到别的表了，怪不得找不到相应字段，折磨了我一晚上（2023/08/03早）"></a>我就栽在最后一步上了，数据库连接到别的表了，怪不得找不到相应字段，折磨了我一晚上（2023/08/03早）</h5></li>
</ul>
<h3 id="表记录-实体类ID自增长"><a href="#表记录-实体类ID自增长" class="headerlink" title="表记录/实体类ID自增长"></a>表记录/实体类ID自增长</h3><ul>
<li><h5 id="如何实现：往数据库表中插入数据记录时，id自增长？"><a href="#如何实现：往数据库表中插入数据记录时，id自增长？" class="headerlink" title="如何实现：往数据库表中插入数据记录时，id自增长？"></a>如何实现：往数据库表中插入数据记录时，id自增长？</h5><ul>
<li><h5 id="建表语句："><a href="#建表语句：" class="headerlink" title="建表语句："></a>建表语句：</h5></li>
</ul>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">`user_id`   <span class="hljs-type">bigint</span> auto_increment <span class="hljs-keyword">primary</span> key comment <span class="hljs-string">&#x27;用户id&#x27;</span>,<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="实体类映射："><a href="#实体类映射：" class="headerlink" title="实体类映射："></a>实体类映射：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">  * 用户id</span><br><span class="hljs-comment">  */</span><br> <span class="hljs-meta">@TableId(type = IdType.ASSIGN_ID)</span><br> <span class="hljs-keyword">private</span> Long userId;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="插入数据："><a href="#插入数据：" class="headerlink" title="插入数据："></a>插入数据：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 3.向数据库中插入用户数据</span><br>       <span class="hljs-type">User</span> <span class="hljs-variable">user</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">User</span>();<br>       user.setUsername(username);<br>       user.setPassword(encryptPassword);<br>       user.setPassword(phone);<br>       user.setAvatar(<span class="hljs-string">&quot;http://ry2s7czdf.hd-bkt.clouddn.com/imgs/avatar/winter_nature_6-wallpaper-2560x1600.jpg&quot;</span>);<br>  <br>       <span class="hljs-type">boolean</span> <span class="hljs-variable">save</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.save(user);<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="表记录：（2023-08-04早）"><a href="#表记录：（2023-08-04早）" class="headerlink" title="表记录：（2023/08/04早）"></a>表记录：（2023/08/04早）</h5></li>
</ul>
<figure class="highlight abnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs abnf"><span class="hljs-attribute">id</span> <span class="hljs-operator">=</span> <span class="hljs-number">1687297781782978562</span><br></code></pre></td></tr></table></figure></li>
</ul>
<h3 id="测试类添加-SpringBootTest注解"><a href="#测试类添加-SpringBootTest注解" class="headerlink" title="测试类添加@SpringBootTest注解"></a>测试类添加@SpringBootTest注解</h3><ul>
<li><h5 id="如果不加这个注解，导入的对象值为null：（2023-08-05午）"><a href="#如果不加这个注解，导入的对象值为null：（2023-08-05午）" class="headerlink" title="如果不加这个注解，导入的对象值为null：（2023/08/05午）"></a>如果不加这个注解，导入的对象值为null：（2023/08/05午）</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">class</span> <span class="hljs-title class_">MemoryClientTest</span> &#123;<br>    <span class="hljs-meta">@Resource</span><br>    <span class="hljs-keyword">private</span> MemoryClient memoryClient;<br><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testMemorySdk</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">if</span>(memoryClient != <span class="hljs-literal">null</span>)&#123;<br>            System.out.println(<span class="hljs-string">&quot;成功了&quot;</span>);<br>            memoryClient.getNameByGet(<span class="hljs-string">&quot;邓哈哈&quot;</span>);<br>            memoryClient.getNameByPost(<span class="hljs-string">&quot;邓嘻嘻&quot;</span>);<br><br><span class="hljs-comment">//        User user = new User();</span><br><span class="hljs-comment">//        user.setName(&quot;邓尼玛&quot;);</span><br>            <span class="hljs-type">User</span> <span class="hljs-variable">user</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">User</span>(<span class="hljs-string">&quot;邓尼玛&quot;</span>);<br>            memoryClient.getUserByPost(user);<br>        &#125;<span class="hljs-keyword">else</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;失败！&quot;</span>);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="还有一点要注意，测试类返回值必须为void，返回其他值会报错：（2023-08-07早）"><a href="#还有一点要注意，测试类返回值必须为void，返回其他值会报错：（2023-08-07早）" class="headerlink" title="还有一点要注意，测试类返回值必须为void，返回其他值会报错：（2023/08/07早）"></a>还有一点要注意，测试类返回值必须为void，返回其他值会报错：（2023/08/07早）</h5></li>
</ul>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql"><span class="hljs-keyword">no</span> test were <span class="hljs-built_in">found</span><br></code></pre></td></tr></table></figure>

<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230807102218377.png" alt="image-20230807102218377"></p>
<h3 id="Enum类不能使用-DATA注解"><a href="#Enum类不能使用-DATA注解" class="headerlink" title="Enum类不能使用@DATA注解"></a>Enum类不能使用@DATA注解</h3><ul>
<li><h5 id="手写-getXXX-setXXX-："><a href="#手写-getXXX-setXXX-：" class="headerlink" title="手写 getXXX() / setXXX()："></a>手写 getXXX() / setXXX()：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">enum</span> <span class="hljs-title class_">WallpaperStatusEnum</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 0 - 公开, 在队伍大厅中可以直接加入</span><br><span class="hljs-comment">     */</span><br>    REVIEW(<span class="hljs-number">0</span>, <span class="hljs-string">&quot;审核中&quot;</span>),<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 1 - 私有, 在队伍大厅中不可以直接加入</span><br><span class="hljs-comment">     */</span><br>    PASS(<span class="hljs-number">1</span>, <span class="hljs-string">&quot;已发布&quot;</span>),<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 2 - 公开且加密, 加入队伍需要密码</span><br><span class="hljs-comment">     */</span><br>    NOPASS(<span class="hljs-number">2</span>, <span class="hljs-string">&quot;不通过&quot;</span>);<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 状态码</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> value;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 状态描述</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> String text;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 判断用户状态</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> value 用户状态</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span> 存在与否</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> WallpaperStatusEnum <span class="hljs-title function_">getEnumByValue</span><span class="hljs-params">(Integer value)</span> &#123;<br>        <span class="hljs-keyword">if</span> (value == <span class="hljs-literal">null</span>) &#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>        &#125;<br>        WallpaperStatusEnum[] values = WallpaperStatusEnum.values();<br>        <span class="hljs-keyword">for</span> (WallpaperStatusEnum teamStatusEnum : values) &#123;<br>            <span class="hljs-keyword">if</span> (teamStatusEnum.getValue() == value) &#123;<br>                <span class="hljs-keyword">return</span> teamStatusEnum;<br>            &#125;<br>        &#125;<br>        <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>    &#125;<br><br>    WallpaperStatusEnum(<span class="hljs-type">int</span> value, String text) &#123;<br>        <span class="hljs-built_in">this</span>.value = value;<br>        <span class="hljs-built_in">this</span>.text = text;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">getValue</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> value;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setValue</span><span class="hljs-params">(<span class="hljs-type">int</span> value)</span> &#123;<br>        <span class="hljs-built_in">this</span>.value = value;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getText</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> text;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setText</span><span class="hljs-params">(String text)</span> &#123;<br>        <span class="hljs-built_in">this</span>.text = text;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="循环依赖"><a href="#循环依赖" class="headerlink" title="循环依赖"></a>循环依赖</h3><ul>
<li><h5 id="我在项目中如此写："><a href="#我在项目中如此写：" class="headerlink" title="我在项目中如此写："></a>我在项目中如此写：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Service</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">WallpaperServiceImpl</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">ServiceImpl</span>&lt;WallpaperMapper, Wallpaper&gt;<br>        <span class="hljs-keyword">implements</span> <span class="hljs-title class_">WallpaperService</span> &#123;<br>         <span class="hljs-meta">@Resource</span><br>         <span class="hljs-keyword">private</span> WallpaperService wallpaperService;<br>         <br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 分页查询</span><br><span class="hljs-comment">     * 分类查询壁纸</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span> 分类壁纸</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> List&lt;Wallpaper&gt; <span class="hljs-title function_">getPageByType</span><span class="hljs-params">(Integer searchType)</span> &#123;<br>        <span class="hljs-keyword">if</span> (WallpaperTypeEnum.getEnumByValue(searchType) == <span class="hljs-literal">null</span>) &#123;<br>            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BusinessException</span>(ErrorCode.PARMS_ERROR, <span class="hljs-string">&quot;没有这样的壁纸类型&quot;</span>);<br>        &#125;<br><br>        QueryWrapper&lt;Wallpaper&gt; type_wqw = <span class="hljs-keyword">new</span> <span class="hljs-title class_">QueryWrapper</span>&lt;&gt;();<br>        type_wqw.eq(<span class="hljs-string">&quot;type&quot;</span>, searchType);<br><br>        <span class="hljs-keyword">return</span> wallpaperService.list(type_wqw);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="产生了循环依赖，会报错："><a href="#产生了循环依赖，会报错：" class="headerlink" title="产生了循环依赖，会报错："></a>产生了循环依赖，会报错：</h5></li>
</ul>
<figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs livecodeserver">Description:<br><br>The dependencies <span class="hljs-keyword">of</span> some <span class="hljs-keyword">of</span> <span class="hljs-keyword">the</span> beans <span class="hljs-keyword">in</span> <span class="hljs-keyword">the</span> application context form <span class="hljs-keyword">a</span> cycle:<br><br>   wallpaperController<br>┌─────┐<br>|  wallpaperServiceImpl<br>└─────┘<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="应该写成这样："><a href="#应该写成这样：" class="headerlink" title="应该写成这样："></a>应该写成这样：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Service</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">WallpaperServiceImpl</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">ServiceImpl</span>&lt;WallpaperMapper, Wallpaper&gt;<br>        <span class="hljs-keyword">implements</span> <span class="hljs-title class_">WallpaperService</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 分页查询</span><br><span class="hljs-comment">     * 分类查询壁纸</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span> 分类壁纸</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> List&lt;Wallpaper&gt; <span class="hljs-title function_">getPageByType</span><span class="hljs-params">(Integer searchType)</span> &#123;<br>        <span class="hljs-keyword">if</span> (WallpaperTypeEnum.getEnumByValue(searchType) == <span class="hljs-literal">null</span>) &#123;<br>            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BusinessException</span>(ErrorCode.PARMS_ERROR, <span class="hljs-string">&quot;没有这样的壁纸类型&quot;</span>);<br>        &#125;<br><br>        QueryWrapper&lt;Wallpaper&gt; type_wqw = <span class="hljs-keyword">new</span> <span class="hljs-title class_">QueryWrapper</span>&lt;&gt;();<br>        type_wqw.eq(<span class="hljs-string">&quot;type&quot;</span>, searchType);<br><br>        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.list(type_wqw);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="时间戳格式问题"><a href="#时间戳格式问题" class="headerlink" title="时间戳格式问题"></a>时间戳格式问题</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@JsonFormat(pattern=&quot;yyyy-MM-dd HH:mm:ss&quot;,timezone = &quot;GMT+8&quot;)</span><br></code></pre></td></tr></table></figure>

<h3 id="MyBatis逻辑删除"><a href="#MyBatis逻辑删除" class="headerlink" title="MyBatis逻辑删除"></a>MyBatis逻辑删除</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 是否删除</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@TableLogic</span><br><span class="hljs-keyword">private</span> Integer isDelete;<br></code></pre></td></tr></table></figure>

<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">mybatis-plus:</span><br>  <span class="hljs-attr">global-config:</span><br>    <span class="hljs-comment"># 逻辑删除</span><br>    <span class="hljs-attr">db-config:</span><br>      <span class="hljs-attr">logic-delete-field:</span> <span class="hljs-string">isDelete</span> <span class="hljs-comment"># 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)</span><br>      <span class="hljs-attr">logic-delete-value:</span> <span class="hljs-number">1</span> <span class="hljs-comment"># 逻辑已删除值(默认为 1)</span><br>      <span class="hljs-attr">logic-not-delete-value:</span> <span class="hljs-number">0</span> <span class="hljs-comment"># 逻辑未删除值(默认为 0)</span><br></code></pre></td></tr></table></figure>

<h3 id="Redis的引入和测试"><a href="#Redis的引入和测试" class="headerlink" title="Redis的引入和测试"></a>Redis的引入和测试</h3><ul>
<li><h5 id="快速实现Redis的引入，主要做到以下几点：（2023-08-07早）"><a href="#快速实现Redis的引入，主要做到以下几点：（2023-08-07早）" class="headerlink" title="快速实现Redis的引入，主要做到以下几点：（2023/08/07早）"></a>快速实现Redis的引入，主要做到以下几点：（2023/08/07早）</h5><ul>
<li>导入相关依赖坐标</li>
<li>作相关yaml配置</li>
<li>作测试</li>
<li>项目引入</li>
</ul>
</li>
<li><h5 id="导入依赖坐标："><a href="#导入依赖坐标：" class="headerlink" title="导入依赖坐标："></a>导入依赖坐标：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs java">&lt;!-- https:<span class="hljs-comment">//mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis --&gt;</span><br>     &lt;dependency&gt;<br>         &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;<br>         &lt;artifactId&gt;spring-boot-starter-data-redis&lt;/artifactId&gt;<br>         &lt;version&gt;<span class="hljs-number">2.6</span><span class="hljs-number">.4</span>&lt;/version&gt;<br>     &lt;/dependency&gt;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="写配置："><a href="#写配置：" class="headerlink" title="写配置："></a>写配置：</h5></li>
</ul>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-comment"># redis 配置</span><br><span class="hljs-attr">redis:</span><br>	<span class="hljs-attr">port:</span> <span class="hljs-number">6379</span><br>	<span class="hljs-attr">host:</span> <span class="hljs-string">localhost</span><br>	<span class="hljs-attr">database:</span> <span class="hljs-number">0</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="作测试："><a href="#作测试：" class="headerlink" title="作测试："></a>作测试：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@SpringBootTest</span><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">UserServiceImplTest</span> &#123;<br>    <span class="hljs-meta">@Resource</span><br>    <span class="hljs-keyword">private</span> RedisTemplate redisTemplate;<br>    <span class="hljs-meta">@Resource</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-type">StringRedisTemplate</span> <span class="hljs-variable">stringRedisTemplate</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StringRedisTemplate</span>();<br><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">loginTest</span><span class="hljs-params">()</span> &#123;<br><br>        <span class="hljs-type">String</span> <span class="hljs-variable">redisKey</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;pic_memories:user:login:session_key&quot;</span>;<br><br><br>        stringRedisTemplate.opsForValue().set(<span class="hljs-string">&quot;pic&quot;</span>, <span class="hljs-string">&quot;memory&quot;</span>);<br>        <br>        stringRedisTemplate.opsForValue().set(redisKey, <span class="hljs-string">&quot;memory&quot;</span>, <span class="hljs-number">20</span>, TimeUnit.HOURS);<br>        redisTemplate.opsForValue().set(redisKey + <span class="hljs-string">&quot;2&quot;</span>, <span class="hljs-string">&quot;memory2&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="这里注意："><a href="#这里注意：" class="headerlink" title="这里注意："></a>这里注意：</h5></li>
<li><h5 id="RedisTemplate-底层的序列化方式，会导致存入的序列化后的value值成为乱码"><a href="#RedisTemplate-底层的序列化方式，会导致存入的序列化后的value值成为乱码" class="headerlink" title="RedisTemplate 底层的序列化方式，会导致存入的序列化后的value值成为乱码"></a>RedisTemplate 底层的序列化方式，会导致存入的序列化后的value值成为乱码</h5></li>
<li><h5 id="StringRedisTemplate-继承了-RedisTemplate-有效解决了这个问题，但只能存放-lt-String，String-gt"><a href="#StringRedisTemplate-继承了-RedisTemplate-有效解决了这个问题，但只能存放-lt-String，String-gt" class="headerlink" title="StringRedisTemplate 继承了 RedisTemplate 有效解决了这个问题，但只能存放&lt;String，String&gt;"></a>StringRedisTemplate 继承了 RedisTemplate 有效解决了这个问题，但只能存放&lt;String，String&gt;</h5></li>
<li><h5 id="综上，我们在使用Redis缓存技术时，可以自己自定义（封装一个）RedisTemplate"><a href="#综上，我们在使用Redis缓存技术时，可以自己自定义（封装一个）RedisTemplate" class="headerlink" title="综上，我们在使用Redis缓存技术时，可以自己自定义（封装一个）RedisTemplate"></a>综上，我们在使用Redis缓存技术时，可以自己自定义（封装一个）RedisTemplate</h5></li>
<li><h5 id="自定义-RedisTemplate-lt-String-Object-gt-config-RedisTemplateConfig"><a href="#自定义-RedisTemplate-lt-String-Object-gt-config-RedisTemplateConfig" class="headerlink" title="自定义 RedisTemplate&lt;String, Object&gt;    (config/RedisTemplateConfig)"></a>自定义 RedisTemplate&lt;String, Object&gt;    (config/RedisTemplateConfig)</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Configuration</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">RedisTemplateConfig</span> &#123;<br>    <span class="hljs-meta">@Bean</span><br>    <span class="hljs-keyword">public</span> RedisTemplate&lt;String, Object&gt; <span class="hljs-title function_">redisTemplate</span><span class="hljs-params">(RedisConnectionFactory connectionFactory)</span> &#123;<br>        <span class="hljs-comment">// 1.创建RedisTemplate对象</span><br>        RedisTemplate&lt;String, Object&gt; redisTemplate = <span class="hljs-keyword">new</span> <span class="hljs-title class_">RedisTemplate</span>&lt;&gt;();<br>        <span class="hljs-comment">// 2.设置连接工厂</span><br>        redisTemplate.setConnectionFactory(connectionFactory);<br>        <span class="hljs-comment">// 3.设置Key的序列化</span><br>        redisTemplate.setKeySerializer(RedisSerializer.string());<br>        <span class="hljs-comment">// 4.创建JSON序列化工具</span><br>        <span class="hljs-type">GenericJackson2JsonRedisSerializer</span> <span class="hljs-variable">jsonRedisSerializer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">GenericJackson2JsonRedisSerializer</span>();<br>        <span class="hljs-comment">// 5.设置value的序列化</span><br>        redisTemplate.setValueSerializer(jsonRedisSerializer);<br>        <span class="hljs-keyword">return</span> redisTemplate;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="解决-RedisTemplate-存入的序列化后的value值成为乱码的问题（2023-08-07早）"><a href="#解决-RedisTemplate-存入的序列化后的value值成为乱码的问题（2023-08-07早）" class="headerlink" title="解决 RedisTemplate 存入的序列化后的value值成为乱码的问题（2023/08/07早）"></a>解决 RedisTemplate 存入的序列化后的value值成为乱码的问题（2023/08/07早）</h5></li>
</ul>
<h3 id="接入阿里云对象存储服务"><a href="#接入阿里云对象存储服务" class="headerlink" title="接入阿里云对象存储服务"></a>接入阿里云对象存储服务</h3><ul>
<li><h5 id="直接看官方文档，写的很全，傻子都会：（2023-08-09午）"><a href="#直接看官方文档，写的很全，傻子都会：（2023-08-09午）" class="headerlink" title="直接看官方文档，写的很全，傻子都会：（2023/08/09午）"></a>直接看官方文档，写的很全，傻子都会：（2023/08/09午）</h5></li>
<li><p><a target="_blank" rel="noopener" href="https://developer.aliyun.com/article/1227235">【案例实战】SpringBoot整合阿里云文件上传OSS-阿里云开发者社区 (aliyun.com)</a></p>
</li>
<li><h5 id="注意以下几点即可："><a href="#注意以下几点即可：" class="headerlink" title="注意以下几点即可："></a>注意以下几点即可：</h5><ul>
<li>yaml配置信息保证无误：</li>
</ul>
<figure class="highlight nestedtext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs nestedtext"><span class="hljs-comment"># 阿里云OSS配置</span><br><span class="hljs-attribute">aliyun</span><span class="hljs-punctuation">:</span><br>  <span class="hljs-attribute">oss</span><span class="hljs-punctuation">:</span><br>    <span class="hljs-attribute">end-point</span><span class="hljs-punctuation">:</span> <span class="hljs-string">oss-cn-beijing.aliyuncs.com</span><br>    <span class="hljs-attribute">access-key-id</span><span class="hljs-punctuation">:</span> <span class="hljs-string">LTAI5t9bAnh9zthSmzTPARM4</span><br>    <span class="hljs-attribute">access-key-secret</span><span class="hljs-punctuation">:</span> <span class="hljs-string">BwV3YKjHp4W2Hk6hYXx1FLbDMO3Qnz</span><br>    <span class="hljs-attribute">bucket-name</span><span class="hljs-punctuation">:</span> <span class="hljs-string">pic-memories</span><br></code></pre></td></tr></table></figure>

<ul>
<li>记得开启对应Bucket的公共读写权限：</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230809182044631.png" alt="image-20230809182044631"></p>
</li>
</ul>
<h3 id="自定义Banner"><a href="#自定义Banner" class="headerlink" title="自定义Banner"></a>自定义Banner</h3><ul>
<li><p>这是IDEA一个很有意思的玩法，自定义项目启动时的banner，详情可以看这篇文章：</p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://juejin.cn/post/7259965990960201787">Spring Boot 自定义启动画面 - 掘金 (juejin.cn)</a></p>
</li>
<li><h5 id="我在-banner-txt-添加的文本如下："><a href="#我在-banner-txt-添加的文本如下：" class="headerlink" title="我在 banner.txt 添加的文本如下："></a>我在 banner.txt 添加的文本如下：</h5></li>
</ul>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs txt">启动成功！<br>$&#123;AnsiColor.BRIGHT_GREEN&#125;<br>   *<br> (  `<br> )\))(    (    )       (   (<br>((_)()\  ))\  (     (  )(  )\ )<br>(_()((_)/((_) )\  &#x27; )\(()\(()/(<br>|  \/  (_)) _((_)) ((_)((_))(_))<br>| |\/| / -_) &#x27;  \() _ \ &#x27;_| || |<br>|_|  |_\___|_|_|_|\___/_|  \_, |<br>                           |__/<br>$&#123;AnsiColor.BRIGHT_WHITE&#125;<br>欢迎使用～<br>spring boot 版本为 $&#123;spring-boot.version&#125;<br>作者：@Memory<br>项目名：PicMemories<br>线上访问地址: 未完成<br><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="获取艺术字：-Text-to-ASCII-Art-Generator-TAAG-patorjk-com-http-patorjk-com-software-taag-p-testall-amp-f-Fire-Font-k-amp-t-Memory"><a href="#获取艺术字：-Text-to-ASCII-Art-Generator-TAAG-patorjk-com-http-patorjk-com-software-taag-p-testall-amp-f-Fire-Font-k-amp-t-Memory" class="headerlink" title="获取艺术字：[Text to ASCII Art Generator (TAAG) (patorjk.com)](http://patorjk.com/software/taag/#p=testall&amp;f=Fire Font-k&amp;t=Memory)"></a>获取艺术字：[Text to ASCII Art Generator (TAAG) (patorjk.com)](<a target="_blank" rel="noopener" href="http://patorjk.com/software/taag/#p=testall&amp;f=Fire">http://patorjk.com/software/taag/#p=testall&amp;f=Fire</a> Font-k&amp;t=Memory)</h5></li>
<li><h5 id="项目启动类处，可以控制是否选择加载-banner-txt-文件：（2023-08-12早）"><a href="#项目启动类处，可以控制是否选择加载-banner-txt-文件：（2023-08-12早）" class="headerlink" title="项目启动类处，可以控制是否选择加载 banner.txt 文件：（2023/08/12早）"></a>项目启动类处，可以控制是否选择加载 banner.txt 文件：（2023/08/12早）</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">import</span> org.springframework.boot.Banner;<br><span class="hljs-keyword">import</span> org.springframework.boot.SpringApplication;<br><span class="hljs-keyword">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;<br><br><span class="hljs-meta">@SpringBootApplication</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">LaunchApplication</span> &#123;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">SpringApplication</span> <span class="hljs-variable">app</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SpringApplication</span>(LaunchApplication.class);<br>        app.setBannerMode(Banner.Mode.OFF); <span class="hljs-comment">// 设置 Banner 模式为关闭</span><br>        app.run(args);<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="主键自增长"><a href="#主键自增长" class="headerlink" title="主键自增长"></a>主键自增长</h3><ul>
<li><h5 id="今天使用MybatisPlus执行插入数据时，发现了这样的报错：（2023-08-15午）"><a href="#今天使用MybatisPlus执行插入数据时，发现了这样的报错：（2023-08-15午）" class="headerlink" title="今天使用MybatisPlus执行插入数据时，发现了这样的报错：（2023/08/15午）"></a>今天使用MybatisPlus执行插入数据时，发现了这样的报错：（2023/08/15午）</h5></li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs shell">org.springframework.jdbc.BadSqlGrammarException: <br><span class="hljs-meta prompt_">#</span><span class="language-bash"><span class="hljs-comment">## Error updating database.  Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near &#x27;like  ( id,</span></span><br>user_id,<br>wallpaper_id )  VALUES  ( 1691349539878477825,<br>168799521293&#x27; at line 1<br><span class="hljs-meta prompt_">#</span><span class="language-bash"><span class="hljs-comment">## The error may exist in com/memory/picmemories/mapper/LikeMapper.java (best guess)</span></span><br><span class="hljs-meta prompt_">#</span><span class="language-bash"><span class="hljs-comment">## The error may involve com.memory.picmemories.mapper.LikeMapper.insert-Inline</span></span><br><span class="hljs-meta prompt_">#</span><span class="language-bash"><span class="hljs-comment">## The error occurred while setting parameters</span></span><br></code></pre></td></tr></table></figure>

<ul>
<li>在上面的栏目《表记录/实体类ID自增长》中，已经实现了如何使记录中的id自增长，这次我就犯了这个错误：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs java">create table `like`<br>(<br>    id           bigint primary key comment <span class="hljs-string">&#x27;点赞id&#x27;</span>,<br>    user_id      bigint                                 not <span class="hljs-literal">null</span> comment <span class="hljs-string">&#x27;点赞用户id&#x27;</span>,<br>    wallpaper_id bigint                                 not <span class="hljs-literal">null</span> comment <span class="hljs-string">&#x27;被点赞的壁纸id&#x27;</span>,<br>    create_time  datetime     <span class="hljs-keyword">default</span> CURRENT_TIMESTAMP not <span class="hljs-literal">null</span> comment <span class="hljs-string">&#x27;创建时间&#x27;</span>,<br>    update_time  datetime     <span class="hljs-keyword">default</span> CURRENT_TIMESTAMP not <span class="hljs-literal">null</span> comment <span class="hljs-string">&#x27;更新时间&#x27;</span>,<br>    is_delete    <span class="hljs-title function_">varchar</span><span class="hljs-params">(<span class="hljs-number">256</span>)</span> <span class="hljs-keyword">default</span> <span class="hljs-string">&#x27;0&#x27;</span>               not <span class="hljs-literal">null</span> comment <span class="hljs-string">&#x27;是否删除&#x27;</span><br>)<br>    comment <span class="hljs-string">&#x27;点赞信息&#x27;</span>;<br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">  * 点赞id</span><br><span class="hljs-comment">  */</span><br> <span class="hljs-meta">@TableId(type = IdType.ASSIGN_ID)</span><br> <span class="hljs-keyword">private</span> Long id;<br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 4.新增记录</span><br> <span class="hljs-type">Like</span> <span class="hljs-variable">like</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Like</span>();<br> like.setUserId(userId);<br> like.setWallpaperId(wallpaperId);<br><br> <span class="hljs-type">boolean</span> <span class="hljs-variable">save</span> <span class="hljs-operator">=</span> likeService.save(like);<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="如上，很显然，我没有将id字段设置为自增长，所以才会出现这样的报错（2023-08-15午）"><a href="#如上，很显然，我没有将id字段设置为自增长，所以才会出现这样的报错（2023-08-15午）" class="headerlink" title="如上，很显然，我没有将id字段设置为自增长，所以才会出现这样的报错（2023/08/15午）"></a>如上，很显然，我没有将id字段设置为自增长，所以才会出现这样的报错（2023/08/15午）</h5></li>
</ul>
<h3 id="修改表字段后要做的那些事"><a href="#修改表字段后要做的那些事" class="headerlink" title="修改表字段后要做的那些事"></a>修改表字段后要做的那些事</h3><ul>
<li><p>修改表字段后，应该做哪些事？</p>
<ul>
<li>修改对应实体属性</li>
<li>修改 XXXmapper.xml 文件（mapper路径、domain路径）</li>
</ul>
</li>
<li><h5 id="使用插件-MybatisX-Generator-快速生成-mapper、domain、service（2023-08-16午）"><a href="#使用插件-MybatisX-Generator-快速生成-mapper、domain、service（2023-08-16午）" class="headerlink" title="使用插件 MybatisX-Generator 快速生成 mapper、domain、service（2023/08/16午）"></a>使用插件 MybatisX-Generator 快速生成 mapper、domain、service（2023/08/16午）</h5></li>
</ul>
<h3 id="YAML配置重复键"><a href="#YAML配置重复键" class="headerlink" title="YAML配置重复键"></a>YAML配置重复键</h3><ul>
<li><h5 id="启动项目报了这样的错误：（2023-08-23晚）"><a href="#启动项目报了这样的错误：（2023-08-23晚）" class="headerlink" title="启动项目报了这样的错误：（2023/08/23晚）"></a>启动项目报了这样的错误：（2023/08/23晚）</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230823164029471.png" alt="image-20230823164029471"></p>
<ul>
<li><h5 id="这个错误通常是由于在YAML配置文件中多次定义了相同的键，检查yaml配置即可"><a href="#这个错误通常是由于在YAML配置文件中多次定义了相同的键，检查yaml配置即可" class="headerlink" title="这个错误通常是由于在YAML配置文件中多次定义了相同的键，检查yaml配置即可"></a>这个错误通常是由于在YAML配置文件中多次定义了相同的键，检查yaml配置即可</h5></li>
</ul>
<h3 id="git合并提交"><a href="#git合并提交" class="headerlink" title="git合并提交"></a>git合并提交</h3><ul>
<li><h5 id="在上午，我使用git进行合并提交项目代码后，下午运行项目，代码变成了这样："><a href="#在上午，我使用git进行合并提交项目代码后，下午运行项目，代码变成了这样：" class="headerlink" title="在上午，我使用git进行合并提交项目代码后，下午运行项目，代码变成了这样："></a>在上午，我使用git进行合并提交项目代码后，下午运行项目，代码变成了这样：</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230826182411757.png" alt="image-20230826182411757"></p>
<ul>
<li><h5 id="没什么大问题，这是因为："><a href="#没什么大问题，这是因为：" class="headerlink" title="没什么大问题，这是因为："></a>没什么大问题，这是因为：</h5></li>
<li><h5 id="你使用git合并推送项目代码后遇到了冲突（conflict），冲突的部分被Git标记为-lt-lt-lt-lt-lt-lt-lt-HEAD-和-gt-gt-gt-gt-gt-gt-gt-。"><a href="#你使用git合并推送项目代码后遇到了冲突（conflict），冲突的部分被Git标记为-lt-lt-lt-lt-lt-lt-lt-HEAD-和-gt-gt-gt-gt-gt-gt-gt-。" class="headerlink" title="你使用git合并推送项目代码后遇到了冲突（conflict），冲突的部分被Git标记为&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD, =======和&gt;&gt;&gt;&gt;&gt;&gt;&gt;。"></a>你使用git合并推送项目代码后遇到了冲突（conflict），冲突的部分被Git标记为&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD, =======和&gt;&gt;&gt;&gt;&gt;&gt;&gt;。</h5></li>
<li><h5 id="这是因为在合并时，Git无法确定如何自动合并这些不同版本的代码。2023-08-26晚）"><a href="#这是因为在合并时，Git无法确定如何自动合并这些不同版本的代码。2023-08-26晚）" class="headerlink" title="这是因为在合并时，Git无法确定如何自动合并这些不同版本的代码。2023/08/26晚）"></a>这是因为在合并时，Git无法确定如何自动合并这些不同版本的代码。2023/08/26晚）</h5></li>
<li><p>为解决冲突，你需要手动编辑冲突的文件，然后再次提交。以下是我采取的一些步骤：</p>
<ul>
<li>打开标记有冲突的文件，找到&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD, =======和&gt;&gt;&gt;&gt;&gt;&gt;&gt;之间的冲突代码段。</li>
<li>理解每个版本的更改，并决定要保留哪些部分。可以选择保留某个版本的代码，或者进行适当的修改以使两个版本的更改合并。</li>
<li>对冲突的代码段进行适当修改，解决冲突。</li>
<li>删除冲突标记（&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD, =======和&gt;&gt;&gt;&gt;&gt;&gt;&gt;）。</li>
<li>完成修改后，保存文件。</li>
</ul>
</li>
<li><h5 id="完成（2023-08-26午）"><a href="#完成（2023-08-26午）" class="headerlink" title="完成（2023/08/26午）"></a>完成（2023/08/26午）</h5></li>
</ul>
<h3 id="Spring项目起不来"><a href="#Spring项目起不来" class="headerlink" title="Spring项目起不来"></a>Spring项目起不来</h3><ul>
<li><h5 id="这个栏目标题起的有点怪啊，不过确实是这么回事：（2023-08-29早）"><a href="#这个栏目标题起的有点怪啊，不过确实是这么回事：（2023-08-29早）" class="headerlink" title="这个栏目标题起的有点怪啊，不过确实是这么回事：（2023/08/29早）"></a>这个栏目标题起的有点怪啊，不过确实是这么回事：（2023/08/29早）</h5></li>
<li><p>今早计划测试一把Spring的定时任务功能，结果构建完成一个SpringBoot项目之后，项目却启动不起来：</p>
</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230829113246414.png" alt="image-20230829113246414"></p>
<ul>
<li><h5 id="准确的说，项目没有启动成为一个Web服务器后台，这是为什么呢？"><a href="#准确的说，项目没有启动成为一个Web服务器后台，这是为什么呢？" class="headerlink" title="准确的说，项目没有启动成为一个Web服务器后台，这是为什么呢？"></a>准确的说，项目没有启动成为一个Web服务器后台，这是为什么呢？</h5></li>
<li><p>妈的，原来是构建项目时，忘记导入相关依赖了：</p>
</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230829112442434.png" alt="image-20230829112442434"></p>
<ul>
<li>即：</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="呐，导入以上依赖后，SpringBoot成功运行起来了：（2023-08-29早）"><a href="#呐，导入以上依赖后，SpringBoot成功运行起来了：（2023-08-29早）" class="headerlink" title="呐，导入以上依赖后，SpringBoot成功运行起来了：（2023/08/29早）"></a>呐，导入以上依赖后，SpringBoot成功运行起来了：（2023/08/29早）</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230829112724037.png" alt="image-20230829112724037"></p>
<ul>
<li><p>真是学傻了，这么基础的问题，平时竟然没注意到，呵呵呵</p>
</li>
<li><h5 id="顺带提一下，SpringBoot项目构建完成后，默认导入以下两个依赖："><a href="#顺带提一下，SpringBoot项目构建完成后，默认导入以下两个依赖：" class="headerlink" title="顺带提一下，SpringBoot项目构建完成后，默认导入以下两个依赖："></a>顺带提一下，SpringBoot项目构建完成后，默认导入以下两个依赖：</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>         <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>         <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>     <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br><br>     <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>         <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>         <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-test<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>         <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>test<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span><br>     <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<h3 id="Spring项目起不来（2）"><a href="#Spring项目起不来（2）" class="headerlink" title="Spring项目起不来（2）"></a>Spring项目起不来（2）</h3><ul>
<li><h5 id="这次是什么原因呢？看报错：（2023-09-06）"><a href="#这次是什么原因呢？看报错：（2023-09-06）" class="headerlink" title="这次是什么原因呢？看报错：（2023/09/06）"></a>这次是什么原因呢？看报错：（2023/09/06）</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230906172719883.png" alt="image-20230906172719883"></p>
<figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs livecodeserver">***************************<br>APPLICATION FAILED TO START<br>***************************<br><br>Description:<br><br>Failed <span class="hljs-built_in">to</span> configure <span class="hljs-keyword">a</span> DataSource: <span class="hljs-string">&#x27;url&#x27;</span> attribute is <span class="hljs-keyword">not</span> specified <span class="hljs-keyword">and</span> no embedded datasource could be configured.<br><br>Reason: Failed <span class="hljs-built_in">to</span> determine <span class="hljs-keyword">a</span> suitable driver class<br><br>Action:<br><br>Consider <span class="hljs-keyword">the</span> following:<br>	If you want <span class="hljs-keyword">an</span> embedded database (H2, HSQL <span class="hljs-keyword">or</span> Derby), please <span class="hljs-built_in">put</span> <span class="hljs-keyword">it</span> <span class="hljs-keyword">on</span> <span class="hljs-title">the</span> <span class="hljs-title">classpath</span>.<br>	If you have database settings <span class="hljs-built_in">to</span> be loaded <span class="hljs-built_in">from</span> <span class="hljs-keyword">a</span> particular profile you may need <span class="hljs-built_in">to</span> activate <span class="hljs-keyword">it</span> (no profiles are currently active).<br><br>Process finished <span class="hljs-keyword">with</span> exit code <span class="hljs-number">1</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="这个就很清晰了，因为引入了数据库相关依赖，却没有作相关配置："><a href="#这个就很清晰了，因为引入了数据库相关依赖，却没有作相关配置：" class="headerlink" title="这个就很清晰了，因为引入了数据库相关依赖，却没有作相关配置："></a>这个就很清晰了，因为引入了数据库相关依赖，却没有作相关配置：</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>           <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.mybatis.spring.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>           <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mybatis-spring-boot-starter<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>           <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.2.2<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>       <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>   <br></code></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>           <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.baomidou<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>           <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mybatis-plus-boot-starter<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>           <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.5.2<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>       <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>mysql<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>mysql-connector-java<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>       <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>8.0.31<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">spring:</span><br>  <span class="hljs-attr">datasource:</span><br>    <span class="hljs-attr">driver-class-name:</span> <span class="hljs-string">com.mysql.cj.jdbc.Driver</span><br>    <span class="hljs-attr">url:</span> <span class="hljs-string">jdbc:mysql://localhost:3306/memory_api</span><br>    <span class="hljs-attr">username:</span> <span class="hljs-string">root</span><br>    <span class="hljs-attr">password:</span> <span class="hljs-string">Dw990831</span><br></code></pre></td></tr></table></figure>

<h3 id="mapper注入为null"><a href="#mapper注入为null" class="headerlink" title="mapper注入为null"></a>mapper注入为null</h3><ul>
<li><h5 id="从来没有踩过这个坑，这次让我记忆深刻了（2023-09-07晚）"><a href="#从来没有踩过这个坑，这次让我记忆深刻了（2023-09-07晚）" class="headerlink" title="从来没有踩过这个坑，这次让我记忆深刻了（2023/09/07晚）"></a>从来没有踩过这个坑，这次让我记忆深刻了（2023/09/07晚）</h5></li>
<li><p>如图，我注入了interfaceInfoMapper</p>
</li>
</ul>
<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230907214553078.png" alt="image-20230907214553078"></p>
<ul>
<li>但项目运行后，通过debug发现，该interfaceInfoMapper为null，为什么注入不成功呢？我犯了一个错误：</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230907214839239.png" alt="image-20230907214839239"></p>
<ul>
<li>如上，我new了一个interfaceIdSource，这个问题被我忽视了：</li>
</ul>
<figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs haxe">类的实例化问题：确保你在使用 InterfaceIdSource 类时是通过 Spring 容器来获取实例，而不是通过 <span class="hljs-keyword">new</span> <span class="hljs-type"></span>关键字手动创建对象。只有通过 Spring 容器管理的对象才会进行自动注入。<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="直接注入即-interfaceIdSource-可解决问题：（2023-09-07晚）"><a href="#直接注入即-interfaceIdSource-可解决问题：（2023-09-07晚）" class="headerlink" title="直接注入即 interfaceIdSource 可解决问题：（2023/09/07晚）"></a>直接注入即 interfaceIdSource 可解决问题：（2023/09/07晚）</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230907215126113.png" alt="image-20230907215126113"></p>
<h3 id="MybatisPlus踩坑记录"><a href="#MybatisPlus踩坑记录" class="headerlink" title="MybatisPlus踩坑记录"></a>MybatisPlus踩坑记录</h3><ul>
<li>我在根据id查询用户时，写了如下代码：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">for</span> (Friends friends : friendsList) &#123;<br>           <span class="hljs-type">Long</span> <span class="hljs-variable">friendId</span> <span class="hljs-operator">=</span> friends.getFriendId();<br>           uqw.eq(<span class="hljs-string">&quot;id&quot;</span>, friendId);<br>           <span class="hljs-type">User</span> <span class="hljs-variable">one</span> <span class="hljs-operator">=</span> userService.getOne(uqw);<br>           userList.add(one);<br>       &#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><p>结果，查出来的 one 对象均为 null，可能是因为 id 设置为了主键</p>
</li>
<li><h5 id="我们改写为MybatisPlus提供的的根据id查询方法，成功解决问题（2023-09-12午）"><a href="#我们改写为MybatisPlus提供的的根据id查询方法，成功解决问题（2023-09-12午）" class="headerlink" title="我们改写为MybatisPlus提供的的根据id查询方法，成功解决问题（2023/09/12午）"></a>我们改写为MybatisPlus提供的的根据id查询方法，成功解决问题（2023/09/12午）</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 2.根据id查询道好友信息</span><br>     <span class="hljs-keyword">for</span> (Friends friends : friendsList) &#123;<br>         <span class="hljs-type">Long</span> <span class="hljs-variable">friendId</span> <span class="hljs-operator">=</span> friends.getFriendId();<br>         <span class="hljs-type">User</span> <span class="hljs-variable">one</span> <span class="hljs-operator">=</span> userService.getById(friendId);<br>         userList.add(one);<br>     &#125;<br></code></pre></td></tr></table></figure>

<h3 id="日常犯傻"><a href="#日常犯傻" class="headerlink" title="日常犯傻"></a>日常犯傻</h3><ul>
<li>使用 Vue 的 ref() 语法时，容易忘记取.value</li>
</ul>
<figure class="highlight abnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs abnf">const currentUserId <span class="hljs-operator">=</span> currentUser.value.id<span class="hljs-comment">;</span><br></code></pre></td></tr></table></figure>

<ul>
<li>访问后端服务器路径，容易忘记写/api</li>
</ul>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">const socketUrl = `ws:<span class="hljs-regexp">//</span>localhost:<span class="hljs-number">8081</span><span class="hljs-regexp">/api/</span>websocket/<span class="hljs-variable">$&#123;currentUserId&#125;</span>`;<br></code></pre></td></tr></table></figure>

<h3 id="导入-Excel-文件"><a href="#导入-Excel-文件" class="headerlink" title="导入 Excel 文件"></a>导入 Excel 文件</h3><ul>
<li><h5 id="Easyexcel-官网：（2023-10-05午）"><a href="#Easyexcel-官网：（2023-10-05午）" class="headerlink" title="Easyexcel 官网：（2023/10/05午）"></a>Easyexcel 官网：（2023/10/05午）</h5></li>
<li><h5 id="关于Easyexcel-Easy-Excel-alibaba-com"><a href="#关于Easyexcel-Easy-Excel-alibaba-com" class="headerlink" title="关于Easyexcel | Easy Excel (alibaba.com)"></a><a target="_blank" rel="noopener" href="https://easyexcel.opensource.alibaba.com/docs/current/">关于Easyexcel | Easy Excel (alibaba.com)</a></h5></li>
<li><h5 id="简单的测试："><a href="#简单的测试：" class="headerlink" title="简单的测试："></a>简单的测试：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">File</span> <span class="hljs-variable">file</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br>      <span class="hljs-keyword">try</span> &#123;<br>          file = ResourceUtils.getFile(<span class="hljs-string">&quot;classpath:test_excel.xlsx&quot;</span>);<br>      &#125; <span class="hljs-keyword">catch</span> (FileNotFoundException e) &#123;<br>          e.printStackTrace();<br>      &#125;<br>      <span class="hljs-comment">// 读取数据</span><br>      List&lt;Map&lt;Integer, String&gt;&gt; list = <span class="hljs-literal">null</span>;<br><br>      list = EasyExcel.read(file)<br>              .excelType(ExcelTypeEnum.XLSX)<br>              .sheet()<br>              .headRowNumber(<span class="hljs-number">0</span>)<br>              .doReadSync();<br>  <br>      <span class="hljs-keyword">if</span> (CollUtil.isEmpty(list)) &#123;<br>          <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;&quot;</span>;<br>      &#125;<br></code></pre></td></tr></table></figure>

<ul>
<li>这部分代码，简单地读取了 <strong>resourse 目录下</strong>的 <strong>test_excel.xlsx 文件</strong>，并<strong>成功获取表格数据</strong></li>
<li>附上原表格数据和解析效果：</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231005162100413.png" alt="image-20231005162100413"></p>
<hr>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231005162143753.png" alt="image-20231005162143753"></p>
<ul>
<li><h5 id="修改代码，接收上传的文件："><a href="#修改代码，接收上传的文件：" class="headerlink" title="修改代码，接收上传的文件："></a>修改代码，接收上传的文件：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 智能分析</span><br><span class="hljs-comment"> *</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> multipartFile       Excel文件</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> genChartByAiRequest 指定图表信息</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> request             request</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@return</span> 生成的图表信息</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@PostMapping(&quot;/generate&quot;)</span><br><span class="hljs-keyword">public</span> BaseResponse&lt;String&gt; <span class="hljs-title function_">uploadFile</span><span class="hljs-params">(<span class="hljs-meta">@RequestPart(&quot;file&quot;)</span> MultipartFile multipartFile,</span><br><span class="hljs-params">                                       GenChartByAiRequest genChartByAiRequest, HttpServletRequest request)</span> &#123;<br>    <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> genChartByAiRequest.getName();<br>    <span class="hljs-type">String</span> <span class="hljs-variable">goal</span> <span class="hljs-operator">=</span> genChartByAiRequest.getGoal();<br>    <span class="hljs-type">String</span> <span class="hljs-variable">chartType</span> <span class="hljs-operator">=</span> genChartByAiRequest.getChartType();<br><br>    <span class="hljs-comment">// 校验</span><br>    ThrowUtils.throwIf(StringUtils.isBlank(goal), ErrorCode.PARAMS_ERROR, <span class="hljs-string">&quot;目标为空&quot;</span>);<br>    ThrowUtils.throwIf(StringUtils.isNotBlank(name) &amp;&amp; name.length() &gt; <span class="hljs-number">100</span>, ErrorCode.PARAMS_ERROR, <span class="hljs-string">&quot;名称过长&quot;</span>);<br><br>    <span class="hljs-type">String</span> <span class="hljs-variable">result</span> <span class="hljs-operator">=</span> ExcelUtils.excelToCsv(multipartFile);<br>    <span class="hljs-keyword">return</span> ResultUtils.success(result);<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="逐行解析-Excle-表格，获取数据："><a href="#逐行解析-Excle-表格，获取数据：" class="headerlink" title="逐行解析 Excle 表格，获取数据："></a>逐行解析 Excle 表格，获取数据：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   * excel 转 csv</span><br><span class="hljs-comment">   *</span><br><span class="hljs-comment">   * <span class="hljs-doctag">@param</span> multipartFile</span><br><span class="hljs-comment">   * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">   */</span><br>  <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title function_">excelToCsv</span><span class="hljs-params">(MultipartFile multipartFile)</span> &#123;<br>      <span class="hljs-type">File</span> <span class="hljs-variable">file</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br>      <span class="hljs-keyword">try</span> &#123;<br>          file = ResourceUtils.getFile(<span class="hljs-string">&quot;classpath:test_excel.xlsx&quot;</span>);<br>      &#125; <span class="hljs-keyword">catch</span> (FileNotFoundException e) &#123;<br>          e.printStackTrace();<br>      &#125;<br>      <span class="hljs-comment">// 读取数据</span><br>      List&lt;Map&lt;Integer, String&gt;&gt; list = <span class="hljs-literal">null</span>;<br>      list = EasyExcel.read(file)<br>              .excelType(ExcelTypeEnum.XLSX)<br>              .sheet()<br>              .headRowNumber(<span class="hljs-number">0</span>)<br>              .doReadSync();<br>      <span class="hljs-keyword">if</span> (CollUtil.isEmpty(list)) &#123;<br>          <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;&quot;</span>;<br>      &#125;<br>      <span class="hljs-comment">// 转换为 csv</span><br>      <span class="hljs-type">StringBuilder</span> <span class="hljs-variable">stringBuilder</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StringBuilder</span>();<br>      <span class="hljs-comment">// 读取表头</span><br>      LinkedHashMap&lt;Integer, String&gt; headerMap = (LinkedHashMap) list.get(<span class="hljs-number">0</span>);<br>      List&lt;String&gt; headerList = headerMap.values().stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());<br>      stringBuilder.append(StringUtils.join(headerList, <span class="hljs-string">&quot;,&quot;</span>)).append(<span class="hljs-string">&quot;\n&quot;</span>);<br>      <span class="hljs-comment">// 读取数据</span><br>      <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">1</span>; i &lt; list.size(); i++) &#123;<br>          LinkedHashMap&lt;Integer, String&gt; dataMap = (LinkedHashMap) list.get(i);<br>          List&lt;String&gt; dataList = dataMap.values().stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());<br>          stringBuilder.append(StringUtils.join(dataList, <span class="hljs-string">&quot;,&quot;</span>)).append(<span class="hljs-string">&quot;\n&quot;</span>);<br>      &#125;<br>      <span class="hljs-keyword">return</span> stringBuilder.toString();<br>  &#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="，我们在接口文档中，上传-Excel-文件："><a href="#，我们在接口文档中，上传-Excel-文件：" class="headerlink" title="，我们在接口文档中，上传 Excel 文件："></a>，我们在接口文档中，上传 Excel 文件：</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231005161702354.png" alt="image-20231005161702354"></p>
<ul>
<li><h5 id="成功解析获取数据并返回："><a href="#成功解析获取数据并返回：" class="headerlink" title="成功解析获取数据并返回："></a>成功解析获取数据并返回：</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231005161948245.png" alt="image-20231005161948245"></p>
<h3 id="校验文件"><a href="#校验文件" class="headerlink" title="校验文件"></a>校验文件</h3><ul>
<li><p>只要涉及到<strong>用户自主上传</strong>操作，一定要校验文件<strong>（图像）</strong></p>
</li>
<li><p>校验：</p>
<ul>
<li><strong>文件大小</strong></li>
<li><strong>文件后缀</strong></li>
<li><strong>文件内容</strong>（成本略高）</li>
<li><strong>文件合规</strong>（敏感内容）</li>
</ul>
</li>
<li><h5 id="校验文件大小和文件后缀"><a href="#校验文件大小和文件后缀" class="headerlink" title="校验文件大小和文件后缀"></a>校验文件大小和文件后缀</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    * 允许上传的文件大小</span><br><span class="hljs-comment">    */</span><br>   <span class="hljs-type">long</span> <span class="hljs-variable">ONE_MB</span> <span class="hljs-operator">=</span> <span class="hljs-number">1024</span> * <span class="hljs-number">1024L</span>;<br><br><br>   <span class="hljs-comment">/**</span><br><span class="hljs-comment">    * 合法的文件后缀</span><br><span class="hljs-comment">    */</span><br>   List&lt;String&gt; VALID_FILE_SUFFIX_LIST = Arrays.asList(<span class="hljs-string">&quot;xlsx&quot;</span>, <span class="hljs-string">&quot;xls&quot;</span>);<br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 3.1.校验文件</span><br>        <span class="hljs-comment">// 3.1.1.校验文件大小</span><br>        <span class="hljs-type">long</span> <span class="hljs-variable">size</span> <span class="hljs-operator">=</span> multipartFile.getSize();<br>        ThrowUtils.throwIf(size &gt; ONE_MB, ErrorCode.PARAMS_ERROR, <span class="hljs-string">&quot;文件超过 1M&quot;</span>);<br><br>        <span class="hljs-comment">// 3.1.2.校验文件后缀</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">originalFilename</span> <span class="hljs-operator">=</span> multipartFile.getOriginalFilename();<br>        <span class="hljs-type">String</span> <span class="hljs-variable">suffix</span> <span class="hljs-operator">=</span> FileUtil.getSuffix(originalFilename);<br>        ThrowUtils.throwIf(!VALID_FILE_SUFFIX_LIST.contains(suffix), ErrorCode.PARAMS_ERROR, <span class="hljs-string">&quot;文件后缀非法&quot;</span>);<br></code></pre></td></tr></table></figure>

<h3 id="限流"><a href="#限流" class="headerlink" title="限流"></a>限流</h3><ul>
<li><p>最近实现 <strong>Memory BI智能分析平台时</strong>，需要限制用户在<strong>单位时间内对智能分析接口的调用次数</strong> <strong>（2023/10/11晚）</strong></p>
</li>
<li><h5 id="面试必备：4种经典限流算法讲解-掘金-juejin-cn"><a href="#面试必备：4种经典限流算法讲解-掘金-juejin-cn" class="headerlink" title="面试必备：4种经典限流算法讲解 - 掘金 (juejin.cn)"></a><a target="_blank" rel="noopener" href="https://juejin.cn/post/6967742960540581918">面试必备：4种经典限流算法讲解 - 掘金 (juejin.cn)</a></h5></li>
<li><h5 id="面试官：来，年轻人！请手撸5种常见限流算法！-Java填坑笔记-博客园-cnblogs-com"><a href="#面试官：来，年轻人！请手撸5种常见限流算法！-Java填坑笔记-博客园-cnblogs-com" class="headerlink" title="面试官：来，年轻人！请手撸5种常见限流算法！ - Java填坑笔记 - 博客园 (cnblogs.com)"></a><a target="_blank" rel="noopener" href="https://www.cnblogs.com/liqiangchn/p/14253924.html">面试官：来，年轻人！请手撸5种常见限流算法！ - Java填坑笔记 - 博客园 (cnblogs.com)</a></h5></li>
<li><p>我们使用 <strong>Redisson</strong> 实现的<strong>令牌桶算法</strong>实现：<strong>调用智能分析接口时，限制用户在单位时间内的调用次数</strong></p>
</li>
<li><h5 id="引入依赖："><a href="#引入依赖：" class="headerlink" title="引入依赖："></a>引入依赖：</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>           <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.redisson<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>           <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>redisson<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>           <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.21.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>       <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="做好相关配置："><a href="#做好相关配置：" class="headerlink" title="做好相关配置："></a>做好相关配置：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Configuration</span><br><span class="hljs-meta">@ConfigurationProperties(prefix = &quot;spring.redis&quot;)</span><br><span class="hljs-meta">@Data</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">RedissionConfig</span> &#123;<br>    <span class="hljs-keyword">private</span> String host;<br><br>    <span class="hljs-keyword">private</span> String port;<br><br>    <span class="hljs-keyword">private</span> String password;<br><br>    <span class="hljs-keyword">private</span> Integer database;<br><br>    <span class="hljs-meta">@Bean</span><br>    <span class="hljs-keyword">public</span> RedissonClient <span class="hljs-title function_">redissonClient</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 1. 创建配置</span><br>        <span class="hljs-type">Config</span> <span class="hljs-variable">config</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Config</span>();<br>        <span class="hljs-type">String</span> <span class="hljs-variable">redisAddress</span> <span class="hljs-operator">=</span> String.format(<span class="hljs-string">&quot;redis://%s:%s&quot;</span>, host, port);<br>        <span class="hljs-comment">//  使用单个Redis，没有开集群 useClusterServers()  设置地址和使用库</span><br>        config.useSingleServer().setAddress(redisAddress).setDatabase(database).setPassword(password);<br>        <span class="hljs-comment">// 2. 创建实例</span><br>        <span class="hljs-keyword">return</span> Redisson.create(config);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">redis:</span><br>   <span class="hljs-attr">port:</span> <span class="hljs-number">6379</span><br>   <span class="hljs-attr">host:</span> <span class="hljs-string">localhost</span><br>   <span class="hljs-attr">database:</span> <span class="hljs-number">1</span><br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="限流实现（区别不同的限流器，每个用户都分别拥有对应的限流器）"><a href="#限流实现（区别不同的限流器，每个用户都分别拥有对应的限流器）" class="headerlink" title="限流实现（区别不同的限流器，每个用户都分别拥有对应的限流器）"></a>限流实现（区别不同的限流器，每个用户都分别拥有对应的限流器）</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    * 限流实现</span><br><span class="hljs-comment">    *</span><br><span class="hljs-comment">    * <span class="hljs-doctag">@param</span> key 识别用户的key</span><br><span class="hljs-comment">    */</span><br>   <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">doRateLimit</span><span class="hljs-params">(String key)</span> &#123;<br>       <span class="hljs-comment">// 创建限流器</span><br>       <span class="hljs-type">RRateLimiter</span> <span class="hljs-variable">rateLimiter</span> <span class="hljs-operator">=</span> redissonClient.getRateLimiter(key);<br>       rateLimiter.trySetRate(RateType.OVERALL, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>, RateIntervalUnit.SECONDS);<br>       <span class="hljs-comment">// 每当一个操作来了之后，请求一个令牌</span><br>       <span class="hljs-type">boolean</span> <span class="hljs-variable">canOp</span> <span class="hljs-operator">=</span> rateLimiter.tryAcquire(<span class="hljs-number">1</span>);<br>       <span class="hljs-comment">// 超出发放令牌数目，请求过于频繁</span><br>       ThrowUtils.throwIf(!canOp, ErrorCode.TOO_MANY_REQUEST);<br>   &#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="简单测试，效果良好，测试结果如下："><a href="#简单测试，效果良好，测试结果如下：" class="headerlink" title="简单测试，效果良好，测试结果如下："></a>简单测试，效果良好，测试结果如下：</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Test</span><br>   <span class="hljs-keyword">void</span> <span class="hljs-title function_">doRateLimit</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> InterruptedException &#123;<br>       <span class="hljs-type">String</span> <span class="hljs-variable">userId</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;1&quot;</span>;<br>       <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">2</span>; i++) &#123;<br>           redisLimiterManager.doRateLimit(userId);<br>           System.out.println(<span class="hljs-string">&quot;成功&quot;</span>);<br>       &#125;<br>       Thread.sleep(<span class="hljs-number">1000</span>);<br>       <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) &#123;<br>           redisLimiterManager.doRateLimit(userId);<br>           System.out.println(<span class="hljs-string">&quot;成功&quot;</span>);<br>       &#125;<br>   &#125;<br></code></pre></td></tr></table></figure>

<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231011180516219.png" alt="image-20231011180516219"></p>
<ul>
<li>业务中使用限流器，<strong>调用智能分析接口时，限制用户在单位时间内的调用次数</strong> <strong>（2023/10/11晚）</strong></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 限流(限制用户的调用次数，以用户id为key，区分各个限流器)</span><br>redisLimiterManager.doRateLimit(<span class="hljs-string">&quot;genCharByAi_&quot;</span> + loginUser.getId());<br></code></pre></td></tr></table></figure>

<h3 id="Slf4j-导入依赖错误"><a href="#Slf4j-导入依赖错误" class="headerlink" title="Slf4j 导入依赖错误"></a>Slf4j 导入依赖错误</h3><ul>
<li>这是个很有意思的问题，起因是我计划<strong>实现一个延迟队列 Demo</strong>，结果在运行时出现了这样的报错：</li>
</ul>
<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20231019123726686.png" alt="image-20231019123726686"></p>
<ul>
<li>这些报错是什么意思呢？简单解释一下：</li>
</ul>
<blockquote>
<p>这些警告信息是由 SLF4J（Simple Logging Facade for Java）引发的，它是一个为 Java 程序提供日志功能的简单抽象层。</p>
<p>警告 <code>No SLF4J providers were found</code> 表示在类路径上未找到任何 SLF4J 提供者。这意味着没有配置合适的日志库实现，导致程序在运行时无法正常输出日志。</p>
<p>警告 <code>Defaulting to no-operation (NOP) logger implementation</code> 表示在缺少真正的日志库实现时，SLF4J 默认使用了一个空操作的日志记录器实现。这意味着代码在运行时不会输出任何日志。</p>
<p>警告 <code>Class path contains SLF4J bindings targeting slf4j-api versions 1.7.x or earlier</code> 表示在类路径上发现了与 SLF4J 绑定，但它们是针对 1.7.x 版本或更早版本的 slf4j-api。这可能导致不兼容或出现日志记录问题。</p>
<p>警告 <code>Ignoring binding found at [jar:file:/D:/softWare/Maven/apache-maven-3.6.1/mvn_resp/ch/qos/logback/logback-classic/1.2.12/logback-classic-1.2.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]</code> 表示 SLF4J 发现了一个冲突的绑定，将被忽略。这意味着在类路径上有多个不同版本的 SLF4J 绑定或日志库实现。</p>
<p>解决这些警告的方法是确保正确配置了 SLF4J 绑定和日志库实现，以及它们的版本兼容性。</p>
</blockquote>
<ul>
<li>同时我也受到了 AI 的点拨，可以从以下几个方面排查问题：</li>
</ul>
<figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">1</span>、确保在项目的依赖管理中添加了正确的 SLF4J 绑定和日志库实现。<br><span class="hljs-attribute">2</span>、确保依赖的版本与所使用的 SLF4J 版本兼容。推荐使用 SLF4J 版本 <span class="hljs-number">1</span>.<span class="hljs-number">7</span>.x 或更高版本。<br><span class="hljs-attribute">3</span>、检查项目的构建路径，确保没有冲突的 SLF4J 绑定存在于类路径上。<br><span class="hljs-attribute">4</span>、如果问题仍然存在，可以尝试在项目中排除掉冲突的 SLF4J 绑定，或通过 Maven 或 Gradle 等构建工具来管理依赖关系。<br><span class="hljs-attribute">5</span>、如果仍然无法解决问题，可以参考 SLF4J 的文档和常见问题页面（https://www.slf4j.org/codes.html）寻找更详细的解决方案。<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="我检查了引入的相关依赖，发现除了-lombok-依赖外，还引入了一个-slf4j-api-依赖："><a href="#我检查了引入的相关依赖，发现除了-lombok-依赖外，还引入了一个-slf4j-api-依赖：" class="headerlink" title="我检查了引入的相关依赖，发现除了 lombok 依赖外，还引入了一个 slf4j-api 依赖："></a>我检查了引入的相关依赖，发现除了 lombok 依赖外，还引入了一个 slf4j-api 依赖：</h5></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>	<span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.projectlombok<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>	<span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>lombok<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>		<span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.slf4j<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>		<span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>slf4j-api<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>		<span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.0.5<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>	<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li>这就是问题所在了，<strong>删除这个依赖即可解决问题</strong>，程序成功运行：<strong>（2023/10/19早）</strong></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231019124205016.png" alt="image-20231019124205016"></p>
<h3 id="实现-updateTime-字段自动更新"><a href="#实现-updateTime-字段自动更新" class="headerlink" title="实现 updateTime 字段自动更新"></a>实现 updateTime 字段自动更新</h3><ul>
<li>什么意思呢？我们希望在<strong>修改完数据库表中的记录</strong>后，该条记录<strong>对应的 uodateTime 字段</strong>实现<strong>自动更新</strong></li>
<li>实现方法很简单，在 IDEA 中，直接修改表的 updateTime 字段属性，如下：</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231107224250849.png" alt="image-20231107224250849"></p>
<ul>
<li>对应的 <strong><code>DDL</code> 语句</strong>是这样的：</li>
</ul>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">updateTime datetime <span class="hljs-keyword">default</span> <span class="hljs-built_in">CURRENT_TIMESTAMP</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">null</span> <span class="hljs-keyword">on</span> <span class="hljs-keyword">update</span> <span class="hljs-built_in">CURRENT_TIMESTAMP</span> comment <span class="hljs-string">&#x27;更新时间&#x27;</span>,<br></code></pre></td></tr></table></figure>

<ul>
<li>这样，我们<strong>更新记录</strong>后，该记录 updateTime 字段会<strong>自动更新为最近修改时间</strong>：<strong>（2023/11/07晚）</strong></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231107224550821.png" alt="image-20231107224550821"></p>
<h3 id="实体类未序列化"><a href="#实体类未序列化" class="headerlink" title="实体类未序列化"></a>实体类未序列化</h3><ul>
<li>我们在后端写接口时，会这样编写接收的参数：<strong>（2023/11/20晚）</strong></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@PostMapping(&quot;/list/page/vo&quot;)</span><br><span class="hljs-keyword">public</span> BaseResponse&lt;Page&lt;Picture&gt;&gt; <span class="hljs-title function_">listPictureByPage</span><span class="hljs-params">(<span class="hljs-meta">@RequestBody</span> Picture picture)</span> <span class="hljs-keyword">throws</span> IOException &#123;<br>    <span class="hljs-comment">// controller层对参数的校验</span><br>    <span class="hljs-type">String</span> <span class="hljs-variable">category</span> <span class="hljs-operator">=</span> picture.getCategory();<br><br>    Page&lt;Picture&gt; picturePage = pictureService.listPictureVOByPage(category);<br>    <span class="hljs-keyword">return</span> ResultUtils.success(picturePage);<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><p>当然，要理解这种接收参数的编写语法，需要系统学习 SpringMVC 的相关内容，这里只谈一点：</p>
<blockquote>
<h5 id="Picture-要支持序列化才能实现网络传输"><a href="#Picture-要支持序列化才能实现网络传输" class="headerlink" title="Picture  要支持序列化才能实现网络传输"></a><code>Picture</code>  要支持序列化才能实现网络传输</h5></blockquote>
</li>
<li><p>妈的，所以才会出现这样的报错：</p>
</li>
</ul>
<figure class="highlight smali"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs smali">om.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct<span class="hljs-built_in"> instance </span>of `memory.cloud.memoryclient.model.domain.Picture` (no Creators, like default<span class="hljs-keyword"> constructor</span>, exist): cannot deserialize from Object value (no delegate-<span class="hljs-built_in"> or </span>property-based Creator)<br> at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2]<br></code></pre></td></tr></table></figure>

<ul>
<li>排了一个小时的错，可算发现了：我编写的 Picture 不支持序列化，改写成如下这样即可：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Data</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Picture</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Serializable</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Picture</span><span class="hljs-params">()</span> &#123;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 所属分类</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> String category;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 图片名</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> String title;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 图片路径</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> String url;<br><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">long</span> <span class="hljs-variable">serialVersionUID</span> <span class="hljs-operator">=</span> <span class="hljs-number">1L</span>;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li>平时这种实体类都是使用 MybatisX-Generator 快速生成的，没注意到<strong>实体类要支持序列化</strong> <strong>（2023/11/20晚）</strong></li>
</ul>
<h3 id="存储数据库编码错误"><a href="#存储数据库编码错误" class="headerlink" title="存储数据库编码错误"></a>存储数据库编码错误</h3><ul>
<li>终于解决了如何正确保存含 <code>emoji</code> 表情数据到数据库中的问题了</li>
<li>直接保存</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><code class="hljs java"> <span class="hljs-comment">// 1. 获取数据</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">url</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;https://juejin.cn/post/7313418992310976549&quot;</span>;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-type">Document</span> <span class="hljs-variable">doc</span> <span class="hljs-operator">=</span> Jsoup.connect(url)<br>                    .userAgent(<span class="hljs-string">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81&quot;</span>)<br>                    .get();<br><br><br>            <span class="hljs-type">Elements</span> <span class="hljs-variable">title</span> <span class="hljs-operator">=</span> doc.select(<span class="hljs-string">&quot;.article-area .article-title&quot;</span>);<br>            System.out.println(<span class="hljs-string">&quot;----------------博文标题----------------&quot;</span>);<br>            System.out.println(title.text());<br><br>            <span class="hljs-type">Elements</span> <span class="hljs-variable">content</span> <span class="hljs-operator">=</span> doc.select(<span class="hljs-string">&quot;.article-viewer p&quot;</span>);<br>            <span class="hljs-comment">// for (Element p : content) &#123;</span><br>            <span class="hljs-comment">//     p.select(&quot;img&quot;).remove();</span><br>            <span class="hljs-comment">//     p.select(&quot;a&quot;).remove();</span><br>            <span class="hljs-comment">// &#125;</span><br><br>            System.out.println(<span class="hljs-string">&quot;---------------博文正文------------------&quot;</span>);<br>            <span class="hljs-comment">// System.out.println(content);</span><br><br>            <span class="hljs-type">byte</span>[] contentBytes = content.toString().getBytes(StandardCharsets.UTF_8);<br><br>            System.out.println(contentBytes);<br>            <span class="hljs-comment">// 获取博文</span><br>            <span class="hljs-type">Article</span> <span class="hljs-variable">article</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Article</span>();<br>            article.setId(Long.valueOf(<span class="hljs-string">&quot;7313418992310976549&quot;</span>));<br>            article.setTitle(title.text());<br>            <br>            <span class="hljs-comment">// 直接保存</span><br>            article.setContent(content.toString());<br><br>            <span class="hljs-comment">// article.setContent(Arrays.toString(contentBytes));</span><br>            <span class="hljs-comment">// article.setContent(content.toString());</span><br>            article.setAuthorId(<span class="hljs-number">0L</span>);<br>            article.setView(<span class="hljs-number">0</span>);<br>            article.setLikes(<span class="hljs-number">0</span>);<br>            article.setComments(<span class="hljs-string">&quot;&quot;</span>);<br>            article.setCollects(<span class="hljs-number">0</span>);<br>            article.setTags(<span class="hljs-string">&quot;&quot;</span>);<br><br>            <span class="hljs-comment">// articleService.save(article);</span><br><br>            <span class="hljs-type">String</span> <span class="hljs-variable">decodedContent</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(contentBytes, StandardCharsets.UTF_8);<br>            System.out.println(<span class="hljs-string">&quot;-------------解码后--------------&quot;</span>);<br>            System.out.println(decodedContent);<br><br>        &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;<br>            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RuntimeException</span>(e);<br>        &#125;<br>    &#125;<br>article.setContent(contentBytes);<br><br></code></pre></td></tr></table></figure>

<ul>
<li>这里直接保存，会出现字符编码无法识别而转换错误，就是因为保存的数据记录中有 emoji 这样的小图标</li>
<li>这里我也查询了相关文章，解决这个问题，虽然最后没有解决，但仍可做参考：</li>
</ul>
<blockquote>
<p>🔥 推荐阅读：</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_32684617/article/details/93495460">用户昵称含emoji表情保存到数据库中报错SQLException: Incorrect string value: ‘\xF0\x9F\x91\xA7’ for colum n …-CSDN博客</a></li>
<li><a target="_blank" rel="noopener" href="https://bbs.csdn.net/topics/392268222">java后台接收获取微信昵称，昵称包含小图标保存到数据库报错-CSDN社区</a></li>
</ul>
</blockquote>
<figure class="highlight subunit"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs subunit"><span class="hljs-keyword">Error </span>updating database.  Cause: java.sql.SQLException: Incorrect string value: &#x27;\xF0\x9F\x8D\x84 \xE5...&#x27; for column &#x27;content&#x27; at row 1<br></code></pre></td></tr></table></figure>

<ul>
<li>经过测试，转码保存解决报错：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">Document</span> <span class="hljs-variable">doc</span> <span class="hljs-operator">=</span> Jsoup.connect(url)<br>                    .userAgent(<span class="hljs-string">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81&quot;</span>)<br>                    .get();<br><br><br><span class="hljs-type">Elements</span> <span class="hljs-variable">title</span> <span class="hljs-operator">=</span> doc.select(<span class="hljs-string">&quot;.article-area .article-title&quot;</span>);<br>System.out.println(<span class="hljs-string">&quot;----------------博文标题----------------&quot;</span>);<br>System.out.println(title.text());<br><br><span class="hljs-type">Elements</span> <span class="hljs-variable">content</span> <span class="hljs-operator">=</span> doc.select(<span class="hljs-string">&quot;.article-viewer p&quot;</span>);<br><span class="hljs-comment">// for (Element p : content) &#123;</span><br><span class="hljs-comment">//     p.select(&quot;img&quot;).remove();</span><br><span class="hljs-comment">//     p.select(&quot;a&quot;).remove();</span><br><span class="hljs-comment">// &#125;</span><br><br>System.out.println(<span class="hljs-string">&quot;---------------博文正文------------------&quot;</span>);<br><span class="hljs-comment">// System.out.println(content);</span><br><br><span class="hljs-type">byte</span>[] contentBytes = content.toString().getBytes(StandardCharsets.UTF_8);<br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">String</span> <span class="hljs-variable">decodedContent</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(contentBytes, StandardCharsets.UTF_8);<br>            System.out.println(<span class="hljs-string">&quot;-------------解码后--------------&quot;</span>);<br>            System.out.println(decodedContent);<br></code></pre></td></tr></table></figure>

<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231224104703715.png" alt="image-20231224104703715"></p>
<ul>
<li>保存到数据库中的问题解决了，接下来就是保证正确从数据库中拿到数据并解码出原数据：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">String</span> <span class="hljs-variable">contentStr</span> <span class="hljs-operator">=</span> article.getContent();<br><span class="hljs-type">byte</span>[] contentBytes = contentStr.getBytes(StandardCharsets.UTF_8);<br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 移除两端的方括号  </span><br><span class="hljs-type">String</span> <span class="hljs-variable">contentStrWithoutBrackets</span> <span class="hljs-operator">=</span> contentStr.substring(<span class="hljs-number">1</span>, contentStr.length() - <span class="hljs-number">1</span>);  <br><span class="hljs-comment">// 使用逗号作为分隔符分割字符串  </span><br>String[] byteStrs = contentStrWithoutBrackets.split(<span class="hljs-string">&quot;,&quot;</span>);  <br><span class="hljs-comment">// 将字符串数组转换为字节数组  </span><br><span class="hljs-type">byte</span>[] contentBytes = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[byteStrs.length];  <br><span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; byteStrs.length; i++) &#123;  <br>    contentBytes[i] = Byte.parseByte(byteStrs[i]);  <br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li>经过诸多尝试，仍无法正确解码</li>
<li>经过前面的测试发现，转码后保存 byte [] 可以解决编码错误，问题是出在保存数据库时</li>
<li>由于字段 content 为 text（varchar 也可以，可能会出现要保存的数据记录过长而导致溢出，就选择 text 了），所以我们在保存 byte [] 到数据库中时，是先转换成字符串再保存的</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs java">article.setContent(Arrays.toString(contentBytes));<br></code></pre></td></tr></table></figure>

<ul>
<li>而后才引发了解码失败的问题，因为对 byte [] 直接解码是可以获取原文内容 content 的，但是先转字符串存入，取出时就不好处理了</li>
<li>那就干脆直接保存 byte [] 到数据库中了，改变字段 content 属性为 blob：</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231224104321929.png" alt="image-20231224104321929"></p>
<ul>
<li>改变对应实体类的字段数据类型为 byte []：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 文章内容</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">private</span> <span class="hljs-type">byte</span>[] content;<br></code></pre></td></tr></table></figure>

<ul>
<li>接下来，我们选择直接保存 byte [] 到数据库中即可：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs java">article.setContent(contentBytes);<br></code></pre></td></tr></table></figure>

<ul>
<li>这里也可以看出，将 byte [] 转字符串数组后保存和直接保存 byte [] 到数据库中的形式是很不一样的（如下图所示）：</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231224104532681.png" alt="image-20231224104532681"></p>
<ul>
<li>接下来，就可以直接从数据库中取出数据并解码了：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">Article</span> <span class="hljs-variable">article</span> <span class="hljs-operator">=</span> articleService.getById(<span class="hljs-number">7313418992310976549L</span>);<br><br><span class="hljs-type">Long</span> <span class="hljs-variable">id</span> <span class="hljs-operator">=</span> article.getId();<br><span class="hljs-type">String</span> <span class="hljs-variable">title</span> <span class="hljs-operator">=</span> article.getTitle();<br><span class="hljs-type">byte</span>[] content = article.getContent();<br><br><span class="hljs-type">String</span> <span class="hljs-variable">decodedContent</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(content, StandardCharsets.UTF_8);<br><span class="hljs-type">Integer</span> <span class="hljs-variable">type</span> <span class="hljs-operator">=</span> article.getType();<br><br>System.out.println(id);<br>System.out.println(title);<br>System.out.println(decodedContent);<br>System.out.println(type);<br></code></pre></td></tr></table></figure>

<ul>
<li>解码结果如下：</li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20231224104725599.png" alt="image-20231224104725599"></p>
<ul>
<li>至此，我们成功解决了如何正确保存数据记录到数据库中的问题，并成功解决了编码问题</li>
</ul>
<h3 id="汉字转拼音"><a href="#汉字转拼音" class="headerlink" title="汉字转拼音"></a>汉字转拼音</h3><ul>
<li>开发 API 接口开放平台的<code>获取随机壁纸接口</code>服务：<a target="_blank" rel="noopener" href="https://www.vcg.com/">视觉中国——全球领先的视觉素材数字版权库和交易平台 (vcg.com)</a></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">Random</span> <span class="hljs-variable">random</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Random</span>();<br><span class="hljs-type">int</span> <span class="hljs-variable">randomPage</span> <span class="hljs-operator">=</span> random.nextInt(<span class="hljs-number">5</span>) + <span class="hljs-number">1</span>;<br><span class="hljs-type">String</span> <span class="hljs-variable">url</span> <span class="hljs-operator">=</span> String.format(<span class="hljs-string">&quot;https://www.vcg.com/creative-image/%s/?page=%d&quot;</span>, category, randomPage);<br><span class="hljs-type">String</span> <span class="hljs-variable">userAgent</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81&quot;</span>;<br></code></pre></td></tr></table></figure>

<ul>
<li>拼接 <code>category </code>，只要是中文字符就不定时出现报错，尝试将中文转为拼音：</li>
<li>导入依赖：<strong>（2024/01/18晚）</strong></li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.belerweb<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>pinyin4j<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.5.1<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> <span class="hljs-comment">&lt;!-- 使用时检查是否有更新的版本 --&gt;</span><br>      <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<ul>
<li>开始转换：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 带声调</span><br><span class="hljs-type">StringBuilder</span> <span class="hljs-variable">output</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StringBuilder</span>();<br>    <span class="hljs-keyword">for</span> (<span class="hljs-type">char</span> c : name.toCharArray()) &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c);<br>            <span class="hljs-keyword">if</span> (pinyinArray != <span class="hljs-literal">null</span> &amp;&amp; pinyinArray.length &gt; <span class="hljs-number">0</span>) &#123;<br>                output.append(pinyinArray[<span class="hljs-number">0</span>]).append(<span class="hljs-string">&quot; &quot;</span>);<br>            &#125; <span class="hljs-keyword">else</span> &#123;<br>                output.append(c).append(<span class="hljs-string">&quot; &quot;</span>);<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            output.append(c).append(<span class="hljs-string">&quot; &quot;</span>);<br>        &#125;<br>    &#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 不带声调</span><br>net.sourceforge.pinyin4j.format.<span class="hljs-type">HanyuPinyinOutputFormat</span> <span class="hljs-variable">format</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">net</span>.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat();<br>       format.setToneType(net.sourceforge.pinyin4j.format.HanyuPinyinToneType.WITHOUT_TONE);<br><br>       <span class="hljs-type">StringBuilder</span> <span class="hljs-variable">output</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StringBuilder</span>();<br>       <span class="hljs-keyword">for</span> (<span class="hljs-type">char</span> c : name.toCharArray()) &#123;<br>           <span class="hljs-keyword">try</span> &#123;<br>               String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);<br>               <span class="hljs-keyword">if</span> (pinyinArray != <span class="hljs-literal">null</span> &amp;&amp; pinyinArray.length &gt; <span class="hljs-number">0</span>) &#123;<br>                   output.append(pinyinArray[<span class="hljs-number">0</span>]).append(<span class="hljs-string">&quot;&quot;</span>);<br>               &#125; <span class="hljs-keyword">else</span> &#123;<br>                   output.append(c);<br>               &#125;<br>           &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>               output.append(c).append(<span class="hljs-string">&quot;&quot;</span>);<br>           &#125;<br>       &#125;<br></code></pre></td></tr></table></figure>

<h3 id="无法加载Spring的配置文件"><a href="#无法加载Spring的配置文件" class="headerlink" title="无法加载Spring的配置文件"></a>无法加载Spring的配置文件</h3><p>启动测试类，发现这样的报错：<strong>（2024/02/13早）</strong></p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240213094455214.png" alt="image-20240213094455214"></p>
<p>在SpringBoot中报错java.lang.IllegalStateException: Failed to load ApplicationContext，无法加载Spring的配置文件</p>
<p>出现这种问题，无外于这几个方面：jar 包过于老旧、@Bean 注入有分歧、配置文件中的数据库连接失败、未扫描到 Mapper</p>
<p>1、jar包有问题或者过老，换最新的试试。<br>2、 内部Bean配置有歧义，Spring自身无法分辨<br>3、缺少某个依赖、或属性的配置<br>4、引用 外部属性文件的情况下，属性文件内有错误，无法加载。比如属性文件配置的数据库连接 有问题<br>5、在使用到applicationContext的 地方引用的路径不正确。</p>
<p>🍖 推荐阅读： <a target="_blank" rel="noopener" href="https://blog.csdn.net/weixin_43235147/article/details/105781532">java.lang.IllegalStateException: Failed to load ApplicationContext-CSDN博客</a></p>
<p>我的问题解决了，确实是配置文件中数据库连接有问题。我这个项目配置了本地 Elasticsearch 的，启动 本地 ES 就好了</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-comment"># Elasticsearch 配置</span><br><span class="hljs-attr">elasticsearch:</span><br>  <span class="hljs-attr">uris:</span> <span class="hljs-string">http://localhost:9200</span><br>  <span class="hljs-attr">username:</span> <span class="hljs-string">root</span><br>  <span class="hljs-attr">password:</span> <span class="hljs-string">******</span><br></code></pre></td></tr></table></figure>

<h3 id="ControllerAdvice-拦截"><a href="#ControllerAdvice-拦截" class="headerlink" title="@ControllerAdvice 拦截"></a>@ControllerAdvice 拦截</h3><blockquote>
<p>2024年4月25日</p>
</blockquote>
<p>🍖 推荐阅读：<a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_43575801/article/details/128891997">@ControllerAdvice 的介绍及三种用法(转载)-CSDN博客</a></p>
<p>在看单位的后端开发代码模板，看到了这个类：</p>
<p>这段代码是一个名为ApiResultHandler的类，它实现了Spring框架中的ResponseBodyAdvice接口。这个类的主要作用是对RestController的接口方法进行拦截，对返回的结果进行处理。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@ControllerAdvice(annotations = &#123;RestController.class&#125;)</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ApiResultHandler</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">ResponseBodyAdvice</span> &#123;<br><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> Class[] annos = &#123;<br>            RequestMapping.class,<br>            GetMapping.class,<br>            PostMapping.class,<br>            DeleteMapping.class,<br>            PutMapping.class<br>    &#125;;<br><br>...............................<br>&#125;<br></code></pre></td></tr></table></figure>

<p>首先，定义了一个静态数组annos，包含了RequestMapping、GetMapping、PostMapping、DeleteMapping和PutMapping这五个注解，用于判断一个方法是否使用了这些注解。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    * 对所有RestController的接口方法进行拦截</span><br><span class="hljs-comment">    */</span><br>   <span class="hljs-meta">@Override</span><br><span class="hljs-keyword">public</span> <span class="hljs-type">boolean</span> <span class="hljs-title function_">supports</span><span class="hljs-params">(MethodParameter returnType, Class converterType)</span> &#123;<br>       <span class="hljs-type">AnnotatedElement</span> <span class="hljs-variable">element</span> <span class="hljs-operator">=</span> returnType.getAnnotatedElement();<br>       <span class="hljs-keyword">return</span> Arrays.stream(annos).anyMatch(anno -&gt; anno.isAnnotation() &amp;&amp; element.isAnnotationPresent(anno));<br>&#125;<br></code></pre></td></tr></table></figure>

<p>重写了supports方法，用于判断当前拦截的方法是否使用了上述五个注解之一。如果使用了，返回true，表示需要拦截；否则返回false，表示不需要拦截。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Override</span><br>   <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">beforeBodyWrite</span><span class="hljs-params">(<span class="hljs-meta">@Nullable</span> Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response)</span> &#123;<br><br>	<span class="hljs-keyword">if</span>(body <span class="hljs-keyword">instanceof</span> RestfulResponse)&#123;<br>		<span class="hljs-keyword">return</span> body;<br>	&#125;<br><br>	<span class="hljs-comment">//feign内部请求，不转格式</span><br>	<span class="hljs-type">HttpHeaders</span> <span class="hljs-variable">headers</span> <span class="hljs-operator">=</span> request.getHeaders();<br>	List&lt;String&gt; list = headers.get(FeginClientConfig.KEEP_ORIGINAL);<br>	<span class="hljs-keyword">if</span>(list != <span class="hljs-literal">null</span> &amp;&amp; list.contains(FeginClientConfig.KEEP_ORIGINAL)) &#123;<br>		<span class="hljs-keyword">return</span> body;<br>	&#125;<br><br>	<span class="hljs-keyword">if</span>(body <span class="hljs-keyword">instanceof</span> ResultCode) &#123;<br>		<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RestfulResponse</span>(((ResultCode) body).getCode(), ((ResultCode) body).getDesc());<br>	&#125;<br><br>   	<span class="hljs-type">AnnotatedElement</span> <span class="hljs-variable">element</span> <span class="hljs-operator">=</span> returnType.getAnnotatedElement();<br>   	<span class="hljs-keyword">if</span>(element.isAnnotationPresent(SuccessfulMessage.class)) &#123;<br>   		<span class="hljs-type">boolean</span> <span class="hljs-variable">ignore</span> <span class="hljs-operator">=</span> element.getAnnotation(SuccessfulMessage.class).ignore();<br>   		<span class="hljs-keyword">if</span>(ignore) &#123;<br>   			<span class="hljs-keyword">return</span> body;<br>   		&#125;<br>   	&#125;<br>   	<br>   	<span class="hljs-type">String</span> <span class="hljs-variable">msg</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br>   	<br>   	<span class="hljs-comment">//1. 配置文件优先级最高</span><br>   	<span class="hljs-comment">//2. 方法上的 SuccessfulMessage</span><br>   	<span class="hljs-comment">//3. 默认</span><br>   	<span class="hljs-comment">//		RequestMapping 成功</span><br>   	<span class="hljs-comment">//		GetMapping 查询成功</span><br>   	<span class="hljs-comment">//		PostMapping 添加成功</span><br>   	<span class="hljs-comment">//		DeleteMapping 删除成功</span><br>   	<span class="hljs-comment">//		PutMapping 修改成功</span><br><br>   	<span class="hljs-keyword">if</span>(element.isAnnotationPresent(SuccessfulMessage.class)) &#123;<br>   		<span class="hljs-comment">/*String value = element.getAnnotation(SuccessfulMessage.class).value();</span><br><span class="hljs-comment">   		//解析EL $&#123;&#125;</span><br><span class="hljs-comment">   		if(value != null) &#123;</span><br><span class="hljs-comment">   			value = value.trim();</span><br><span class="hljs-comment">   			if(value.startsWith(&quot;$&#123;&quot;) &amp;&amp; value.endsWith(&quot;&#125;&quot;)) &#123;</span><br><span class="hljs-comment">   				value = value.substring(2, value.length()-1);</span><br><span class="hljs-comment">   				String[] separator = StringUtils.splitByWholeSeparator(value, &quot;:&quot;);</span><br><span class="hljs-comment">   				String key = separator[0];</span><br><span class="hljs-comment">   				String defaultValue = separator.length &gt; 1 ? separator[1] : null;</span><br><span class="hljs-comment">   				//查询配置文件</span><br><span class="hljs-comment">   				msg = env.getProperty(key, defaultValue);</span><br><span class="hljs-comment">   			&#125; else &#123;</span><br><span class="hljs-comment">   				msg = value;</span><br><span class="hljs-comment">   			&#125;</span><br><span class="hljs-comment">   		&#125;*/</span><br>		msg = element.getAnnotation(SuccessfulMessage.class).value();<br>   	&#125;<br>   	<br>   	<span class="hljs-keyword">if</span>(msg == <span class="hljs-literal">null</span>) &#123;<br>   		<span class="hljs-keyword">if</span>(element.isAnnotationPresent(GetMapping.class)) &#123;<br>   			msg = <span class="hljs-string">&quot;操作成功&quot;</span>;<br>   		&#125; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(element.isAnnotationPresent(PostMapping.class)) &#123;<br>   			msg = <span class="hljs-string">&quot;操作成功&quot;</span>;<br>   		&#125; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(element.isAnnotationPresent(PutMapping.class)) &#123;<br>   			msg = <span class="hljs-string">&quot;修改成功&quot;</span>;<br>   		&#125; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(element.isAnnotationPresent(DeleteMapping.class)) &#123;<br>   			msg = <span class="hljs-string">&quot;删除成功&quot;</span>;<br>   		&#125; <span class="hljs-keyword">else</span> &#123;<br>   			msg = <span class="hljs-string">&quot;请求成功&quot;</span>;<br>   		&#125;<br>   	&#125;<br>       <span class="hljs-keyword">return</span> RestfulResponse.success(msg, body);<br>   &#125;<br></code></pre></td></tr></table></figure>

<p>重写了beforeBodyWrite方法，这个方法会在Controller方法执行后，返回结果之前被调用。在这个方法中，对返回的结果进行了处理：</p>
<ul>
<li>如果返回的结果已经是RestfulResponse类型，直接返回；</li>
<li>如果请求头中包含FeginClientConfig.KEEP_ORIGINAL，表示是内部请求，不进行格式转换，直接返回；</li>
<li>如果返回的结果是ResultCode类型，将其转换为RestfulResponse类型并返回；</li>
<li>如果方法上有SuccessfulMessage注解，根据注解的属性决定是否忽略该次拦截；</li>
<li>根据方法上的注解（如GetMapping、PostMapping等）设置默认的成功消息；</li>
<li>最后，将成功消息和原始结果封装成RestfulResponse对象并返回。</li>
</ul>
<h3 id="定时任务实现"><a href="#定时任务实现" class="headerlink" title="定时任务实现"></a>定时任务实现</h3><ul>
<li><p>思来想去，这个栏目还是写在这儿比较合适，介绍一下在Java中，如何写一个<strong>定时任务</strong></p>
</li>
<li><h5 id="推荐阅读：我终于会写-Java-的定时任务了！-掘金-juejin-cn"><a href="#推荐阅读：我终于会写-Java-的定时任务了！-掘金-juejin-cn" class="headerlink" title="推荐阅读：我终于会写 Java 的定时任务了！ - 掘金 (juejin.cn)"></a>推荐阅读：<a target="_blank" rel="noopener" href="https://juejin.cn/post/7158851405531316254">我终于会写 Java 的定时任务了！ - 掘金 (juejin.cn)</a></h5></li>
</ul>
<h4 id="纯手写单线程循环"><a href="#纯手写单线程循环" class="headerlink" title="纯手写单线程循环"></a>纯手写单线程循环</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">timer1</span><span class="hljs-params">()</span> &#123;<br>     <span class="hljs-keyword">new</span> <span class="hljs-title class_">Thread</span>(() -&gt; &#123;<br>         <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>             System.out.println(<span class="hljs-string">&quot;定时任务A 当前时间: &quot;</span> + LocalDateTime.now());<br>             <span class="hljs-keyword">try</span> &#123;<br>                 Thread.sleep(<span class="hljs-number">1000</span>);<br>             &#125; <span class="hljs-keyword">catch</span> (InterruptedException e) &#123;<br>                 <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RuntimeException</span>(e);<br>             &#125;<br>         &#125;<br>     &#125;).start();<br> &#125;<br></code></pre></td></tr></table></figure>

<h4 id="Timer和他的小伙伴"><a href="#Timer和他的小伙伴" class="headerlink" title="Timer和他的小伙伴"></a>Timer和他的小伙伴</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">timer2</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 单线程</span><br>        <span class="hljs-type">Timer</span> <span class="hljs-variable">timer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Timer</span>();<br>        System.out.println(<span class="hljs-string">&quot;1秒后执行任务A，A完成后，等待1秒开始定时执行任务B，当前时间: &quot;</span> + LocalDateTime.now());<br>        <span class="hljs-comment">// 1秒后执行</span><br>        timer.schedule(<span class="hljs-keyword">new</span> <span class="hljs-title class_">TimerTask</span>() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>                System.out.println(<span class="hljs-string">&quot;定时任务A 当前时间: &quot;</span> + LocalDateTime.now());<br>            &#125;<br>        &#125;, <span class="hljs-number">1000</span>); <span class="hljs-comment">// 这里 1000，就是代表延迟 1000 毫秒后再执行</span><br><br>        <span class="hljs-comment">// 每隔2秒执行一次这个任务</span><br>        timer.schedule(<span class="hljs-keyword">new</span> <span class="hljs-title class_">TimerTask</span>() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>                System.out.println(<span class="hljs-string">&quot;定时任务B 当前时间: &quot;</span> + LocalDateTime.now());<br>            &#125;<br>        &#125;, <span class="hljs-number">1000</span>, <span class="hljs-number">2000</span>); <span class="hljs-comment">// 1000 同理，2000 即执行完本次任务后，隔 2000 毫秒后再一次执行，达到定时任务的效果</span><br>    &#125;<br></code></pre></td></tr></table></figure>

<h4 id="ScheduledExecutorService"><a href="#ScheduledExecutorService" class="headerlink" title="ScheduledExecutorService"></a>ScheduledExecutorService</h4><ul>
<li><h5 id="定时执行"><a href="#定时执行" class="headerlink" title="定时执行"></a>定时执行</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">timer4</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-type">ScheduledExecutorService</span> <span class="hljs-variable">scheduledExecutorService</span> <span class="hljs-operator">=</span> Executors.newSingleThreadScheduledExecutor();<br>        System.out.println(<span class="hljs-string">&quot;2秒后开始执行任务，此刻时间---&quot;</span> + LocalDateTime.now());<br>        <span class="hljs-comment">// 固定频率（每隔5秒）开始执行一个任务</span><br>        scheduledExecutorService.scheduleAtFixedRate(() -&gt; &#123;<br>            System.out.println(<span class="hljs-string">&quot;任务开始---&quot;</span> + LocalDateTime.now());<br>            <span class="hljs-keyword">try</span> &#123;<br>                Thread.sleep(<span class="hljs-number">2000</span>);<br>            &#125; <span class="hljs-keyword">catch</span> (InterruptedException e) &#123;<br>                e.printStackTrace();<br>            &#125;<br>            System.out.println(<span class="hljs-string">&quot;任务结束---&quot;</span> + LocalDateTime.now());<br>        &#125;, <span class="hljs-number">2000</span>, <span class="hljs-number">5000</span>, TimeUnit.MILLISECONDS);<br>    &#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="延时执行"><a href="#延时执行" class="headerlink" title="延时执行"></a>延时执行</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">timer5</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-type">ScheduledExecutorService</span> <span class="hljs-variable">scheduledExecutorService</span> <span class="hljs-operator">=</span> Executors.newSingleThreadScheduledExecutor();<br>        System.out.println(<span class="hljs-string">&quot;2秒后开始执行任务，此刻时间---&quot;</span> + LocalDateTime.now());<br>        <span class="hljs-comment">// 任务完成后间隔4秒开始执行下一次任务</span><br>        scheduledExecutorService.scheduleWithFixedDelay(() -&gt; &#123;<br>            System.out.println(<span class="hljs-string">&quot;任务开始---&quot;</span> + LocalDateTime.now());<br>            <span class="hljs-keyword">try</span> &#123;<br>                Thread.sleep(<span class="hljs-number">2000</span>);<br>            &#125; <span class="hljs-keyword">catch</span> (InterruptedException e) &#123;<br>                e.printStackTrace();<br>            &#125;<br>            System.out.println(<span class="hljs-string">&quot;任务结束---&quot;</span> + LocalDateTime.now());<br>        &#125;, <span class="hljs-number">2000</span>, <span class="hljs-number">4000</span>, TimeUnit.MILLISECONDS);<br>    &#125;<br></code></pre></td></tr></table></figure>

<h4 id="DelayQueue-延迟任务"><a href="#DelayQueue-延迟任务" class="headerlink" title="DelayQueue 延迟任务"></a>DelayQueue 延迟任务</h4><ul>
<li><h5 id="DelayQueue是JDK提供的api，是一个延迟队列"><a href="#DelayQueue是JDK提供的api，是一个延迟队列" class="headerlink" title="DelayQueue是JDK提供的api，是一个延迟队列"></a>DelayQueue是JDK提供的api，是一个延迟队列</h5></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">DelayQueueDemo</span> &#123;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        DelayQueue&lt;SanYouTask&gt; sanYouTaskDelayQueue = <span class="hljs-keyword">new</span> <span class="hljs-title class_">DelayQueue</span>&lt;&gt;();<br><br>        <span class="hljs-keyword">new</span> <span class="hljs-title class_">Thread</span>(() -&gt; &#123;<br>            <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>                <span class="hljs-keyword">try</span> &#123;<br>                    <span class="hljs-type">SanYouTask</span> <span class="hljs-variable">sanYouTask</span> <span class="hljs-operator">=</span> sanYouTaskDelayQueue.take();<br>                    log.info(<span class="hljs-string">&quot;获取到延迟任务:&#123;&#125;&quot;</span>, sanYouTask.getTaskContent());<br>                &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>                &#125;<br>            &#125;<br>        &#125;).start();<br><br>        log.info(<span class="hljs-string">&quot;提交延迟任务&quot;</span>);<br>        sanYouTaskDelayQueue.offer(<span class="hljs-keyword">new</span> <span class="hljs-title class_">SanYouTask</span>(<span class="hljs-string">&quot;三友的java日记5s&quot;</span>, <span class="hljs-number">5L</span>));<br>        sanYouTaskDelayQueue.offer(<span class="hljs-keyword">new</span> <span class="hljs-title class_">SanYouTask</span>(<span class="hljs-string">&quot;三友的java日记3s&quot;</span>, <span class="hljs-number">3L</span>));<br>        sanYouTaskDelayQueue.offer(<span class="hljs-keyword">new</span> <span class="hljs-title class_">SanYouTask</span>(<span class="hljs-string">&quot;三友的java日记8s&quot;</span>, <span class="hljs-number">8L</span>));<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Data</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">SanYouTask</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Delayed</span> &#123;<br><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> String taskContent;<br><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Long triggerTime;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">SanYouTask</span><span class="hljs-params">(String taskContent, Long delayTime)</span> &#123;<br>        <span class="hljs-built_in">this</span>.taskContent = taskContent;<br>        <span class="hljs-built_in">this</span>.triggerTime = System.currentTimeMillis() + delayTime * <span class="hljs-number">1000</span>;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">long</span> <span class="hljs-title function_">getDelay</span><span class="hljs-params">(TimeUnit unit)</span> &#123;<br>        <span class="hljs-keyword">return</span> unit.convert(triggerTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">compareTo</span><span class="hljs-params">(Delayed o)</span> &#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.triggerTime.compareTo(((SanYouTask) o).triggerTime);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><code>getDelay</code>方法返回<strong>这个任务还剩多久时间可以执行</strong>，小于0的时候说明可以这个延迟任务到了执行的时间了。</li>
<li><code>compareTo</code>这个是<strong>对任务排序</strong>的，保证最先到延迟时间的任务排到队列的头。<ul>
<li><strong>taskContent</strong>：延迟任务的具体的内容</li>
<li><strong>delayTime</strong>：延迟时间，秒为单位</li>
</ul>
</li>
</ul>
<h5 id="实现原理"><a href="#实现原理" class="headerlink" title="实现原理"></a>实现原理</h5><blockquote>
<p>🍻 <code>offer</code>方法在提交任务的时候，会通过根据<code>compareTo</code>的实现对任务进行排序，将最先需要被执行的任务放到队列头。</p>
<p>🍛<code>take</code>方法获取任务的时候，会拿到队列头部的元素，也就是队列中最早需要被执行的任务，通过getDelay返回值判断任务是否需要被立刻执行，如果需要的话，就返回任务，如果不需要就会等待这个任务到延迟时间的剩余时间，当时间到了就会将任务返回。</p>
</blockquote>
<ul>
<li>效果如下：</li>
</ul>
<h4 id="Spring提供定时任务"><a href="#Spring提供定时任务" class="headerlink" title="Spring提供定时任务"></a>Spring提供定时任务</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author</span> 邓哈哈</span><br><span class="hljs-comment"> * 2023/8/29 11:50</span><br><span class="hljs-comment"> * Function:</span><br><span class="hljs-comment"> * Version 1.0</span><br><span class="hljs-comment"> */</span><br> <br><span class="hljs-meta">@EnableScheduling</span><br><span class="hljs-meta">@Component</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Timer</span> &#123;<br>    <span class="hljs-meta">@Scheduled(cron = &quot;*/2 * * * * *&quot;)</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">timer</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;哈哈哈哈&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><h5 id="如果有多个定时任务类，可以考虑把-EnableScheduling注解添加在启动类上"><a href="#如果有多个定时任务类，可以考虑把-EnableScheduling注解添加在启动类上" class="headerlink" title="如果有多个定时任务类，可以考虑把@EnableScheduling注解添加在启动类上"></a>如果有多个定时任务类，可以考虑把@EnableScheduling注解添加在启动类上</h5></li>
</ul>
<h4 id="Cron表达式"><a href="#Cron表达式" class="headerlink" title="Cron表达式"></a>Cron表达式</h4><ul>
<li><h5 id="在线生成工具：在线Cron表达式生成器-qqe2-com"><a href="#在线生成工具：在线Cron表达式生成器-qqe2-com" class="headerlink" title="在线生成工具：在线Cron表达式生成器 (qqe2.com)"></a>在线生成工具：<a target="_blank" rel="noopener" href="https://cron.qqe2.com/">在线Cron表达式生成器 (qqe2.com)</a></h5></li>
<li><h5 id="简单地介绍下如何使用吧：（2023-08-25早）"><a href="#简单地介绍下如何使用吧：（2023-08-25早）" class="headerlink" title="简单地介绍下如何使用吧：（2023/08/25早）"></a>简单地介绍下如何使用吧：（2023/08/25早）</h5></li>
</ul>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230829122937976.png" alt="image-20230829122937976"></p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230829123041111.png" alt="image-20230829123041111"></p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20230829123201856.png" alt="image-20230829123201856"></p>
<h3 id="代码合并"><a href="#代码合并" class="headerlink" title="代码合并"></a>代码合并</h3><blockquote>
<p>2024年5月22日</p>
</blockquote>
<p>今天学习：在团队协同开发工作中，如何使用 IDEA 整合的 git 功能实现<strong>本地代码提交至远程仓库</strong>。</p>
<p>选择要提交的文件：</p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240522114357514.png" alt="image-20240522114357514"></p>
<p>编写完毕 commit 信息后，选择好分支，拉取远程仓库最新代码：</p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240522114503426.png" alt="image-20240522114503426"></p>
<p>直接 push 即可：</p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240522114610086.png" alt="image-20240522114610086"></p>
<h3 id="IDEA-连接-MySQL-失败"><a href="#IDEA-连接-MySQL-失败" class="headerlink" title="IDEA 连接 MySQL 失败"></a>IDEA 连接 MySQL 失败</h3><blockquote>
<p>2024年5月29日</p>
</blockquote>
<p>经过排查，发现是从 maven 下载 MySQL 驱动失败了，</p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240529080517771.png" alt="image-20240529080517771"></p>
<p>只好是手动指定本地 MySQL 驱动路径，直接在本机的 maven 目录下找就可以，我的在这：</p>
<figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">D</span>:\softWare\Maven\apache-maven-<span class="hljs-number">3</span>.<span class="hljs-number">6</span>.<span class="hljs-number">1</span>\mvn_resp\mysql<br></code></pre></td></tr></table></figure>

<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240529082955156.png" alt="image-20240529082955156"></p>
<p>设置下时区，有两种设置方法：</p>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/weixin_44190665/article/details/115601295">解决：Server returns invalid timezone. Need to set ‘serverTimezone‘ property._server returns invalid timezone. need to set ‘serv-CSDN博客</a></p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240529081423926.png" alt="image-20240529081423926"></p>
<p>确实解决了问题：</p>
<figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">DBMS</span>: MySQL (ver. <span class="hljs-number">5</span>.<span class="hljs-number">7</span>.<span class="hljs-number">19</span>-log)<br><span class="hljs-attribute">Case</span> sensitivity: plain=lower, delimited=lower<br><span class="hljs-attribute">Driver</span>: MySQL Connector/J (ver. mysql-connector-java-<span class="hljs-number">8</span>.<span class="hljs-number">0</span>.<span class="hljs-number">21</span> (Revision: <span class="hljs-number">33</span>f65445a1bcc544eb0120491926484da168f199), JDBC4.<span class="hljs-number">2</span>)<br><br><span class="hljs-attribute">Ping</span>: <span class="hljs-number">33</span> ms<br><span class="hljs-attribute">SSL</span>: no<br></code></pre></td></tr></table></figure>

<p>但是连接上了 MySQL，却不显示数据库，显示为空是什么情况。</p>
<p>参考：<a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_62124267/article/details/132100787">【IDEA连接MySQL服务后不显示本地数据库？——这样做！】_idea的数据库内容没办法显示-CSDN博客</a></p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240529083348441.png" alt="image-20240529083348441"></p>
<p>那是因为我连接数据库时没有选定具体数据库，默认只有系统自带的。</p>
<p>可以如上图一样勾选，也可以在连接数据库时的配置中填充，就不会出现这样的问题：</p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240529083514118.png" alt="image-20240529083514118"></p>
<h3 id="Swagger-文档"><a href="#Swagger-文档" class="headerlink" title="Swagger 文档"></a>Swagger 文档</h3><blockquote>
<p>2024年5月29日</p>
</blockquote>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">spring:</span><br>    <span class="hljs-attr">server:</span><br>      <span class="hljs-attr">address:</span> <span class="hljs-string">localhost</span><br>      <span class="hljs-attr">port:</span> <span class="hljs-number">8101</span><br>      <span class="hljs-attr">servlet:</span><br>        <span class="hljs-attr">context-path:</span> <span class="hljs-string">/api</span><br></code></pre></td></tr></table></figure>

<p>在项目启动入口如此编写：统计启动时间，读取配置获取 <strong>ip、端口号和路径</strong>。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@SpringBootApplication(exclude = &#123;RedisAutoConfiguration.class&#125;)</span><br><span class="hljs-meta">@MapperScan(&quot;com.yupi.springbootinit.mapper&quot;)</span><br><span class="hljs-meta">@EnableScheduling</span><br><span class="hljs-meta">@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)</span><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MainApplication</span> &#123;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">ConfigurableApplicationContext</span> <span class="hljs-variable">ctx</span> <span class="hljs-operator">=</span> SpringApplication.run(MainApplication.class, args);<br>        <span class="hljs-type">long</span> <span class="hljs-variable">start</span> <span class="hljs-operator">=</span> System.currentTimeMillis();<br><br><br>        <span class="hljs-type">long</span> <span class="hljs-variable">time</span> <span class="hljs-operator">=</span> (System.currentTimeMillis() - start) / <span class="hljs-number">1000</span>;<br>        <span class="hljs-type">String</span> <span class="hljs-variable">info</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;启动完成，耗时%d秒，swagger访问链接：http://%s:%s%s/doc.html&quot;</span>;<br>        <span class="hljs-type">String</span> <span class="hljs-variable">address</span> <span class="hljs-operator">=</span> ctx.getEnvironment().getProperty(<span class="hljs-string">&quot;server.address&quot;</span>);<br>        <span class="hljs-type">String</span> <span class="hljs-variable">port</span> <span class="hljs-operator">=</span> ctx.getEnvironment().getProperty(<span class="hljs-string">&quot;server.port&quot;</span>);<br>        <span class="hljs-type">String</span> <span class="hljs-variable">path</span> <span class="hljs-operator">=</span> ctx.getEnvironment().getProperty(<span class="hljs-string">&quot;server.servlet.context-path&quot;</span>);<br>        log.info(String.format(info, time, address, port, path));<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>

<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240529090430264.png" alt="image-20240529090430264"></p>
<p>这样启动项目后，很便捷地就能访问到 swagger 接口文档了：</p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240529090523288.png" alt="image-20240529090523288"></p>
<h3 id="YAML-格式有误"><a href="#YAML-格式有误" class="headerlink" title="YAML 格式有误"></a>YAML 格式有误</h3><blockquote>
<p>2024年6月1日</p>
</blockquote>
<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20240603100138051.png" alt="image-20240603100138051"></p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240607082241950.png" alt="image-20240607082241950"></p>
<p>今天上午遇到的报错：</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs stylus"><span class="hljs-number">09</span>:<span class="hljs-number">56</span>:<span class="hljs-number">32.110</span> <span class="hljs-selector-attr">[restartedMain]</span> ERROR org<span class="hljs-selector-class">.springframework</span><span class="hljs-selector-class">.boot</span><span class="hljs-selector-class">.SpringApplication</span> - Application run failed<br>org<span class="hljs-selector-class">.yaml</span><span class="hljs-selector-class">.snakeyaml</span><span class="hljs-selector-class">.error</span><span class="hljs-selector-class">.YAMLException</span>: java<span class="hljs-selector-class">.nio</span><span class="hljs-selector-class">.charset</span><span class="hljs-selector-class">.MalformedInputException</span>: Input length = <span class="hljs-number">1</span><br></code></pre></td></tr></table></figure>

<p>这个错误日志显示你的Spring Boot应用程序在尝试启动时遇到了问题，特别是在解析YAML配置文件时。错误 <code>org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1</code> 通常意味着YAML解析器在读取配置文件时遇到了字符编码问题。</p>
<p>具体来说，<code>MalformedInputException</code> 指的是输入数据（在这里是YAML配置文件）与期望的字符编码格式不匹配。这可能是因为：</p>
<ol>
<li>YAML文件可能包含无法用当前字符集（通常是UTF-8）解码的字符。</li>
<li>YAML文件可能已被保存为不同的字符编码格式（如ISO-8859-1或其他）。</li>
<li>在读取或处理YAML文件时，可能指定了错误的字符编码。</li>
</ol>
<p>最后发现是因为不小心缩进了一下 application.yaml 配置文件，改回来就好了。</p>
<h3 id="Spring-Cloud-依赖版本"><a href="#Spring-Cloud-依赖版本" class="headerlink" title="Spring Cloud 依赖版本"></a>Spring Cloud 依赖版本</h3><blockquote>
<p>2024年6月7日</p>
</blockquote>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240606160142339.png"> </p>
<p>🍖 推荐阅读：<a target="_blank" rel="noopener" href="https://sca.aliyun.com/docs/2021/overview/version-explain/?spm=5176.29160081.0.0.74801a157QLVDg">版本发布说明 | https://sca.aliyun.com</a></p>
<h3 id="Nacos-未配置"><a href="#Nacos-未配置" class="headerlink" title="Nacos 未配置"></a>Nacos 未配置</h3><blockquote>
<p>2024年6月7日</p>
</blockquote>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240607082241950.png" alt="image-20240607082241950"></p>
<p>这个问题真的恶心，一直提醒我 yaml 配置文件有误，也不知道是格式有误还是少配置了些东西：</p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240607083651186.png" alt="image-20240607083651186"></p>
<p>我把配置文件删得只剩端口号了，它才提示我检测到 nacos 依赖，却没有扫描到相关配置。</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs routeros"><span class="hljs-built_in">Add</span> a spring.config.<span class="hljs-attribute">import</span>=nacos: property <span class="hljs-keyword">to</span> your configuration.<br>	<span class="hljs-keyword">If</span> configuration is <span class="hljs-keyword">not</span> required <span class="hljs-built_in">add</span> spring.config.<span class="hljs-attribute">import</span>=optional:nacos: instead.<br>	<span class="hljs-keyword">To</span> <span class="hljs-built_in">disable</span> this check, <span class="hljs-built_in">set</span> spring.cloud.nacos.config.import-check.<span class="hljs-attribute">enabled</span>=<span class="hljs-literal">false</span>.<br></code></pre></td></tr></table></figure>

<p>要么配置不检测 nacos 相关配置，要么显示配置 nacos。</p>
<p>妈的就不能直接提示么。</p>
<p>还有一个问题，坑死我了。</p>
<p>yaml 配置文件里最好不要写中文注释，否则也会不停地提示你配置文件格式有误，你还找不到哪里有问题。</p>
<h3 id="找不着主类"><a href="#找不着主类" class="headerlink" title="找不着主类"></a>找不着主类</h3><blockquote>
<p>2024年6月7日</p>
</blockquote>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240607083156819.png" alt="image-20240607083156819"></p>
<p>怪了，我好像也没怎么改配置吧，突然就行了：</p>
<p><img src="C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20240607110520450.png" alt="image-20240607110520450"></p>
<h3 id="依赖配置心得"><a href="#依赖配置心得" class="headerlink" title="依赖配置心得"></a>依赖配置心得</h3><blockquote>
<p>2024年6月7日</p>
</blockquote>
<ol>
<li>有些公共依赖不要搞在父项目中，比如 Swagger、MybatisPlus 这些</li>
<li>微服务项目一定要注意版本兼容，Spring Boot，Spring Cloud Alibaba，Spring Cloud 这些。</li>
</ol>
<h3 id="日志输出"><a href="#日志输出" class="headerlink" title="日志输出"></a>日志输出</h3><blockquote>
<p>2024年6月7日</p>
</blockquote>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">logging:</span><br>  <span class="hljs-attr">level:</span><br>    <span class="hljs-attr">root:</span> <span class="hljs-string">INFO</span><br>    <span class="hljs-attr">org:</span><br>      <span class="hljs-attr">springframework:</span> <span class="hljs-string">INFO</span><br>      <span class="hljs-attr">springframework.web:</span> <span class="hljs-string">INFO</span><br>      <span class="hljs-attr">springframework.boot.autoconfigure:</span> <span class="hljs-string">WARN</span><br></code></pre></td></tr></table></figure>

<p>搞这么个配置，启动项目后的日志打印就清晰多了：</p>
<p><img src="https://gitee.com/deng-2022/pictures/raw/master/images/image-20240607101425070.png" alt="image-20240607101425070"></p>
<h1 id="总结-1"><a href="#总结-1" class="headerlink" title="总结"></a>总结</h1>
                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/memory_blog/categories/SpringBoot/" class="category-chain-item">SpringBoot</a>
  
  
    <span>></span>
    
  <a href="/memory_blog/categories/SpringBoot/Mybatis/" class="category-chain-item">Mybatis</a>
  
  
    <span>></span>
    
  <a href="/memory_blog/categories/SpringBoot/Mybatis/Redis/" class="category-chain-item">Redis</a>
  
  
    <span>></span>
    
  <a href="/memory_blog/categories/SpringBoot/Mybatis/Redis/%E9%98%BF%E9%87%8C%E4%BA%91OSS/" class="category-chain-item">阿里云OSS</a>
  
  
    <span>></span>
    
  <a href="/memory_blog/categories/SpringBoot/Mybatis/Redis/%E9%98%BF%E9%87%8C%E4%BA%91OSS/%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3/" class="category-chain-item">接口文档</a>
  
  
    <span>></span>
    
  <a href="/memory_blog/categories/SpringBoot/Mybatis/Redis/%E9%98%BF%E9%87%8C%E4%BA%91OSS/%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3/%E7%BB%8F%E9%AA%8C/" class="category-chain-item">经验</a>
  
  
    <span>></span>
    
  <a href="/memory_blog/categories/SpringBoot/Mybatis/Redis/%E9%98%BF%E9%87%8C%E4%BA%91OSS/%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3/%E7%BB%8F%E9%AA%8C/%E9%A1%B9%E7%9B%AE/" class="category-chain-item">项目</a>
  
  

  

  

  

  

  

  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/memory_blog/tags/%E7%BB%8F%E9%AA%8C/">#经验</a>
      
        <a href="/memory_blog/tags/%E9%A1%B9%E7%9B%AE/">#项目</a>
      
        <a href="/memory_blog/tags/Redis/">#Redis</a>
      
        <a href="/memory_blog/tags/SpringBoot/">#SpringBoot</a>
      
        <a href="/memory_blog/tags/Mybatis/">#Mybatis</a>
      
        <a href="/memory_blog/tags/%E9%98%BF%E9%87%8C%E4%BA%91OSS/">#阿里云OSS</a>
      
        <a href="/memory_blog/tags/%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3/">#接口文档</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>凤凰涅槃：Spring Boot 开发之路上的坎坷与成长</div>
      <div>https://test.atomgit.net/memory_blog/2023/07/06/凤凰涅槃：Spring Boot 开发之路上的坎坷与成长/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>Memory</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2023年7月6日</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>更新于</div>
          <div>2024年6月4日</div>
        </div>
      
      
        <div class="license-meta-item">
          <div>许可协议</div>
          <div>
            
              
              
                <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
                  <span class="hint--top hint--rounded" aria-label="BY - 署名">
                    <i class="iconfont icon-by"></i>
                  </span>
                </a>
              
            
          </div>
        </div>
      
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/memory_blog/2023/07/11/%E4%BB%8EIP%E5%88%B0Ping%E5%91%BD%E4%BB%A4%EF%BC%9A%E4%BA%86%E8%A7%A3%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E8%BF%9E%E6%8E%A5%E7%9A%84%E5%9F%BA%E7%A1%80/" title="从IP到Ping命令：了解计算机网络连接的基础">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">从IP到Ping命令：了解计算机网络连接的基础</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/memory_blog/2023/07/06/%E6%89%93%E9%80%A0%E6%B5%81%E7%95%85%E7%BC%96%E7%A0%81%E4%B9%8B%E6%97%85%EF%BC%9AIntelliJ%20IDEA%20%E7%9A%84%E9%AB%98%E6%95%88%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7%E4%B8%8E%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B%E4%BC%98%E5%8C%96/" title="打造流畅编码之旅：IntelliJ IDEA 的高效使用技巧与工作流程优化">
                        <span class="hidden-mobile">打造流畅编码之旅：IntelliJ IDEA 的高效使用技巧与工作流程优化</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
  
  
    <article id="comments">
      

    </article>
  


          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header">
    <i class="iconfont icon-list"></i>
    <span>目录</span>
  </p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <a href="https://hexo.fluid-dev.com/docs/guide/" target="_blank" rel="nofollow noopener"> <span>Memory | 个人文档站点</span> </a>
<i class="iconfont icon-love"></i> <a href="https://hexo.fluid-dev.com/docs/guide/" target="_blank" rel="nofollow noopener"> <span>配置指南 | Hexo Fluid 用户手册</span> </a>   
    </div>
  
  
    <div class="statistics">
  
  

  
    
      <span id="leancloud-site-pv-container" style="display: none">
        总访问量 
        <span id="leancloud-site-pv"></span>
         次
      </span>
    
    
      <span id="leancloud-site-uv-container" style="display: none">
        总访客数 
        <span id="leancloud-site-uv"></span>
         人
      </span>
    
    

  
</div>

  
  
    <!-- 备案信息 ICP for China -->
    <div class="beian">
  <span>
    <a href="http://beian.miit.gov.cn/" target="_blank" rel="nofollow noopener">
      京ICP证123456号
    </a>
  </span>
  
    
      <span>
        <a
          href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=12345678"
          rel="nofollow noopener"
          class="beian-police"
          target="_blank"
        >
          
            <span style="visibility: hidden; width: 0">|</span>
            <img src="/memory_blog/img/police_beian.png" alt="police-icon"/>
          
          <span>京公网安备12345678号</span>
        </a>
      </span>
    
  
</div>

  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/memory_blog/js/events.js" ></script>
<script  src="/memory_blog/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>







  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init(Object.assign({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      scrollSmooth    : true,
      includeTitleTags: true,
      headingsOffset  : -boardTop,
    }, CONFIG.toc));
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }

    Fluid.events.registerRefreshCallback(function() {
      if ('tocbot' in window) {
        tocbot.refresh();
        var toc = jQuery('#toc');
        if (toc.length === 0 || !tocbot) {
          return;
        }
        if (toc.find('.toc-list-item').length > 0) {
          toc.css('visibility', 'visible');
        }
      }
    });
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.11/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));

    Fluid.events.registerRefreshCallback(function() {
      if ('anchors' in window) {
        anchors.removeAll();
        var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
        var res = [];
        for (var item of el) {
          res.push('.markdown-body > ' + item.trim());
        }
        if (CONFIG.anchorjs.placement === 'left') {
          anchors.options.class = 'anchorjs-link-left';
        }
        anchors.add(res.join(', '));
      }
    });
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/memory_blog/js/local-search.js" ></script>

  <script defer src="/memory_blog/js/leancloud.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/memory_blog/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
